27 #include <Classes.hpp>
28 #include <Controls.hpp>
29 #include <StdCtrls.hpp>
31 #include <Buttons.hpp>
32 #include <ExtCtrls.hpp>
34 #include <Dialogs.hpp>
35 #include <Graphics.hpp>
36 #include <ComCtrls.hpp>
37 #include <Clipbrd.hpp>
61 #include <Filectrl.hpp>
64 #include <Vcl.HTMLHelpViewer.hpp>
65 #pragma package(smart_init)
66 #pragma link "Vcl.HTMLHelpViewer" //added at v2.0.0 for access to the .chm help file
67 #pragma resource "*.dfm"
89 Screen->Cursor = TCursor(-11);
102 CurDir = AnsiString(GetCurrentDir());
104 UnicodeString FullProgramName = GetModuleName(0);
106 UnicodeString ProgramName = ExtractFileName(FullProgramName);
108 UnicodeString ProgramDirectoryName = ExtractFilePath(FullProgramName);
111 if(!FileExists(ProgramName))
113 if(!SetCurrentDir(ProgramDirectoryName))
115 ShowMessage(
"The working directory does not contain the railway executable file so the program cannot "
116 "open. This is usually because the program has been selected via the right-click taskbar icon though it may "
117 "also happen in other circumstances. It is caused by the Windows operating system re-assigning the "
118 "working directory for some unknown reason, though whether or not it happens appears to depend on the "
119 "Windows update version.\n\n"
120 "To avoid this happening please open the program by double clicking the program icon on the desktop "
121 "if there is one, or the program icon shown in Windows Explorer.");
122 Application->Terminate();
126 CurDir = AnsiString(GetCurrentDir());
184 "program operation will be restricted");
186 Application->HelpFile = AnsiString(
CurDir +
"\\Help.chm");
194 int DispW = (Screen->Width - 64) / 16;
195 int DispH = (Screen->Height - 192) / 16;
199 Display =
new TDisplay(
MainScreen,
PerformanceLogBox,
OutputLog1,
OutputLog2,
OutputLog3,
OutputLog4,
OutputLog5,
OutputLog6,
OutputLog7,
OutputLog8,
387 SpeedButton96->Glyph->LoadFromResourceName(0,
"ConcourseGlyph");
451 FontButton->Glyph->LoadFromResourceName(0,
"FontGraphic");
452 HomeButton->Glyph->LoadFromResourceName(0,
"Home");
471 SetGapsButton->Glyph->LoadFromResourceName(0,
"ConnectGaps");
483 CallOnImage->Picture->Bitmap->LoadFromResourceName(0,
"CallingOn");
484 CrashImage->Picture->Bitmap->LoadFromResourceName(0,
"CrashWarning");
485 DerailImage->Picture->Bitmap->LoadFromResourceName(0,
"DerailWarning");
486 SignalStopImage->Picture->Bitmap->LoadFromResourceName(0,
"SignalStopWarning");
487 SPADImage->Picture->Bitmap->LoadFromResourceName(0,
"SPADWarning");
488 TrainFailedImage->Picture->Bitmap->LoadFromResourceName(0,
"TrainFailedWarning");
489 ManualLCDownImage->Picture->Bitmap->LoadFromResourceName(0,
"ManualLCDownImage");
491 DistanceKey->Picture->Bitmap->LoadFromResourceName(0,
"DistanceKey");
492 PrefDirKey->Picture->Bitmap->LoadFromResourceName(0,
"PrefDirKey");
494 TrackLinkedImage->Picture->Bitmap->LoadFromResourceName(0,
"TrackLinkedGraphic");
496 GapsNotSetImage->Picture->Bitmap->LoadFromResourceName(0,
"GapsNotSetGraphic");
497 GapsSetImage->Picture->Bitmap->LoadFromResourceName(0,
"GapsSetGraphic");
511 AnsiString NL =
'\n';
512 const AnsiString TTLabelStr1 =
"Start new train" + NL +
"Start new service from a split" + NL +
"Start new service from another service" + NL +
513 "Start new non-repeating shuttle finish service" + NL +
"Start new shuttle train at a timetabled stop" + NL +
514 "Start new shuttle service from a feeder";
516 const AnsiString TTLabelStr2 =
"Pass" + NL +
"Be joined by another train" + NL +
"Front split" + NL +
"Rear split" + NL +
"Change direction of train";
518 const AnsiString TTLabelStr3 =
"Finish && form a new service" + NL +
"Finish && join another train" + NL +
"Finish && exit railway" + NL +
519 "Finish && repeat shuttle, finally remain here" + NL +
"Finish && repeat shuttle, finally form a finishing service" + NL +
520 "Finish non-repeating shuttle feeder service" + NL +
"Finish && remain here";
522 const AnsiString TTLabelStr4 =
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
523 "HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
" " +
526 const AnsiString TTLabelStr5 =
"HH:MM ';' Location" + NL +
"HH:MM ';' HH:MM ';' Location";
528 const AnsiString TTLabelStr6 =
"+ rear element ID - space - front element ID [+ optional ';S']" + NL +
"+ ref. of the train that splits" + NL +
529 "+ other service ref." + NL +
"+ shuttle service ref." + NL +
"+ rear element ID - space - front element ID ';' linked shuttle ref." + NL +
530 "+ linked shuttle service ref. ';' feeder service ref." + NL +
"+ location" + NL +
"+ joining train ref." + NL +
"+ new service ref." + NL +
531 "+ new service ref." + NL +
" " + NL +
"+ new service ref." + NL +
"+ ref. of train to join" + NL +
532 "+ list of valid exit element IDs (at least 1) separated by spaces" + NL +
"+ linked shuttle service ref.";
534 const AnsiString TTLabelStr7 =
"Arrival OR departure time (program will determine which from the context) + location." + NL +
535 "Arrival time, departure time (with no events between) + location";
537 const AnsiString TTLabelStr9 =
"Timetable entries" + NL +
"(service references etc.)";
538 const AnsiString TTLabelStr11 =
"Timetable" + NL +
"start time";
540 const AnsiString TTLabelStr12 =
"NB: WITHIN SERVICES commas must" + NL +
"not be used (have special meanings)," + NL +
541 "and semicolons may only be used to" + NL +
"separate service components.";
543 const AnsiString TTLabelStr13 =
"+ linked shuttle service ref. ';' finishing service ref." + NL +
"+ linked shuttle service ref.";
545 const AnsiString TTLabelStr15 =
"Repeat the service + ';' minutes between repeats ';' digit increment ';' number of repeats (last line of service)";
568 if((Screen->Width < 1024) || (Screen->Height < 768))
570 ShowMessage(
"Please note that this program works best with a screen resolution of at least 1024 x 768. Please change if possible");
575 WindowState = wsMaximized;
586 Screen->Cursor = TCursor(-2);
644 char *LocalNumericInformation = setlocale(LC_NUMERIC,
"");
646 if(LocalNumericInformation ==
"")
651 struct lconv *conv = &Locale;
657 catch(
const EFOpenError &e)
661 MessageDlg(e.Message +
" - program must terminate", mtError, But, 0);
662 Application->Terminate();
665 catch(
const Exception &e)
669 AnsiString Message =
"A fatal error occurred during the program setup process, the program must terminate. Message = " + e.Message;
670 MessageDlg(Message, mtError, But, 0);
672 Application->Terminate();
707 catch(
const Exception &e)
724 catch(
const Exception &e)
745 Screen->Cursor = TCursor(-2);
755 Screen->Cursor = TCursor(-2);
769 catch(
const Exception &e)
788 catch(
const Exception &e)
801 UnicodeString strVersion = L
"N/A";
803 VersionSize = GetFileVersionInfoSizeW(Application->ExeName.c_str(), &VersionHandle);
806 pBuffer =
new BYTE[VersionSize];
808 if(GetFileVersionInfoW(Application->ExeName.c_str(), VersionHandle, VersionSize, pBuffer))
810 VS_FIXEDFILEINFO *fi;
814 if(VerQueryValueW(pBuffer, L
"\\", (
void**)&fi, &buflen))
817 strVersion.sprintf(L
"%d.%d.%d", HIWORD(fi->dwFileVersionMS), LOWORD(fi->dwFileVersionMS), HIWORD(fi->dwFileVersionLS));
823 return(L
" v" + strVersion);
839 catch(
const Exception &e)
858 catch(
const Exception &e)
872 if(((TSpeedButton*)Sender)->Down)
883 Screen->Cursor = TCursor(-11);
884 InfoPanel->Caption =
"SELECTING: Filling area with chosen element";
885 bool FillSelectionFlag =
false;
888 UnicodeString MessageStr =
889 "Click 'Yes' to fill the area with the chosen element or 'No' to abort.\n" "Existing elements won't be overwritten although track can\n"
890 "have platforms and non-station named location elements added.\n\nThis message will not be shown again.";
891 int button = Application->MessageBox(MessageStr.c_str(), L
"", MB_YESNO);
894 FillSelectionFlag =
true;
899 bool TrackLinkingRequiredFlag =
true;
928 Screen->Cursor = TCursor(-2);
939 catch(
const Exception &e)
952 Screen->Cursor = TCursor(-11);
982 ShowMessage(
"Incomplete track or other error - see highlighted element (it may be behind this message "
983 "which can be moved by left clicking the mouse in the title bar and dragging it).");
989 Screen->Cursor = TCursor(-2);
996 ShowMessage(
"Unable to set any track links");
1001 Screen->Cursor = TCursor(-2);
1024 ShowMessage(
"Successful Completion");
1025 Screen->Cursor = TCursor(-2);
1028 catch(
const Exception &e)
1049 catch(
const Exception &e)
1068 catch(
const Exception &e)
1087 catch(
const Exception &e)
1106 TFont *TempFont =
new TFont;
1114 TempText.
Font = DisplayFont;
1122 else if(Key ==
'\x1B')
1132 catch(
const Exception &e)
1151 catch(
const Exception &e)
1166 ShowMessage(
"Error, location name being entered without an entry in LNPendingList");
1186 Screen->Cursor = TCursor(-11);
1189 AnsiString ExistingName;
1203 UnicodeString MessageStr = UnicodeString(
"Another location named '") +
LocationNameTextBox->Text +
1204 UnicodeString(
"' already exists. If you continue its name will be erased. Do you wish to continue?");
1205 int button = Application->MessageBox(MessageStr.c_str(), L
"Warning!", MB_YESNO | MB_ICONWARNING);
1209 Screen->Cursor = TCursor(-2);
1220 bool UseExistingPosition =
false;
1229 if(ExistingName !=
"")
1233 UseExistingPosition =
true;
1237 Screen->Cursor = TCursor(-2);
1252 bool UseExistingPosition =
false;
1255 UseExistingPosition =
true;
1259 Screen->Cursor = TCursor(-2);
1272 LocStr = LocStr.Trim();
1281 if((LocStr !=
"") && (LocStr[1] >=
'0') && (LocStr[1] <=
'9'))
1283 Screen->Cursor = TCursor(-2);
1284 ShowMessage(
"Location name can't begin with a number");
1292 if(LocStr.Length() > 50)
1294 Screen->Cursor = TCursor(-2);
1295 ShowMessage(
"Location name too long, 50 characters maximum");
1303 for(
int x = 1; x <= LocStr.Length(); x++)
1305 char Ch = LocStr[x];
1306 if((Ch !=
' ') && (Ch !=
'&') && (Ch !=
'(') && (Ch !=
')') && (Ch !=
':') && (Ch != 39) && (Ch !=
'.') && (Ch !=
'-') && (Ch !=
'+') &&
1307 (Ch !=
'/') && ((Ch <
'0') || (Ch >
'9')) && ((Ch <
'A') || (Ch >
'Z')) && ((Ch <
'a') || (Ch >
'z')))
1309 Screen->Cursor = TCursor(-2);
1311 "Location name contains one or more invalid characters, must be alphanumeric, brackets, space, full stop, colon, inverted comma, '-', '+', '/' or '&&'");
1322 Screen->Cursor = TCursor(-2);
1323 ShowMessage(
"Location name cannot be 'cdt', this name would interfere with the timetable");
1334 bool UseExistingPosition =
false;
1335 if(ExistingName !=
"")
1339 UseExistingPosition =
true;
1343 Screen->Cursor = TCursor(-2);
1352 Screen->Cursor = TCursor(-2);
1355 catch(
const Exception &e)
1376 catch(
const Exception &e)
1390 int Dist = 0, SpeedLimit = 0;
1394 DistanceStr =
"No change";
1399 SpeedStr =
"No change";
1403 if(DistanceStr ==
"No change")
1407 if(SpeedStr ==
"No change")
1423 if(((Dist != -1) && (DistanceStr.Length() > 6)) || ((SpeedLimit != -1) && (SpeedStr.Length() > 6)))
1425 ShowMessage(
"One or more entries too long");
1429 if((DistanceStr ==
"") || (SpeedStr ==
""))
1431 ShowMessage(
"One or more entries blank");
1437 for(
int x = 1; x <= DistanceStr.Length(); x++)
1439 if((DistanceStr[x] <
'0') || (DistanceStr[x] >
'9'))
1441 ShowMessage(
"Track length value must be a positive whole number, or blank for no change");
1449 for(
int x = 1; x <= DistanceStr.Length(); x++)
1451 if((DistanceStr[x] <
'0') || (DistanceStr[x] >
'9'))
1453 ShowMessage(
"Distance must be a positive whole number");
1461 for(
int x = 1; x <= SpeedStr.Length(); x++)
1463 if((SpeedStr[x] <
'0') || (SpeedStr[x] >
'9'))
1465 ShowMessage(
"Speed limit must be a positive whole number, or blank for no change");
1473 for(
int x = 1; x <= SpeedStr.Length(); x++)
1475 if((SpeedStr[x] <
'0') || (SpeedStr[x] >
'9'))
1477 ShowMessage(
"Speed limit must be a positive whole number, or 'Mixed'");
1485 Dist = DistanceStr.ToInt();
1487 if(SpeedLimit != -1)
1489 SpeedLimit = SpeedStr.ToInt();
1498 if(((Dist != -1) && (Dist < 10)) || ((SpeedLimit != -1) && (SpeedLimit < 10)) || ((SpeedLimit != -1) && (SpeedLimit >
TTrain::MaximumSpeedLimit)))
1501 ShowMessage(
"Lengths must be 10m or more, and speeds must be between 10km/h and 400km/h");
1514 bool NamedLocPresent =
false;
1517 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1519 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1523 NamedLocPresent =
true;
1528 if(NamedLocPresent && (Dist < 50))
1532 ShowMessage(
"Note: Named location elements are quite short. If they are too short the simulation might be too unrealistic.\n\nThis message will not be shown again.");
1536 if(NamedLocPresent && (Dist > 200))
1540 ShowMessage(
"Note: Named location elements are quite long. If they are too long the simulation might be too unrealistic.\n\nThis message will not be shown again.");
1544 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1546 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1583 catch(
const Exception &e)
1606 catch(
const Exception &e)
1618 TMsgDlgButtons Buttons;
1619 Buttons << mbYes << mbNo;
1620 if(MessageDlg(
"This will reset the selected elements to default lengths & speed limits. Proceed?", mtWarning, Buttons, 0) == mrNo)
1639 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1641 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1695 throw Exception(
"Error, XLinkPos > 1 in SetOneDefaultTrackLength at " + AnsiString(TrackElement.
HLoc) +
" & " +
1696 AnsiString(TrackElement.
VLoc));
1712 catch(
const Exception &e)
1724 TMsgDlgButtons Buttons;
1725 Buttons << mbYes << mbNo;
1726 if(MessageDlg(
"This will reset ALL track elements to default lengths & speed limits. Proceed?", mtWarning, Buttons, 0) == mrNo)
1748 catch(
const Exception &e)
1776 bool GraphicFoundInVector =
false;
1777 for(TTrack::TUserGraphicVector::iterator UGVIt =
Track->
UserGraphicVector.begin(); UGVIt < Track->UserGraphicVector.end(); UGVIt++)
1779 if(UGMIt->first == UGVIt->FileName)
1781 GraphicFoundInVector =
true;
1785 if(!GraphicFoundInVector)
1787 delete UGMIt->second;
1803 catch(
const Exception &e)
1843 catch(
const Exception &e)
1882 catch(
const Exception &e)
1912 catch(
const Exception &e)
1938 catch(
const Exception &e)
1957 catch(
const Exception &e)
1972 ShowMessage(
"No preferred direction selection");
1976 Screen->Cursor = TCursor(-11);
1983 Screen->Cursor = TCursor(-2);
1986 catch(
const Exception &e)
1999 TMsgDlgButtons Buttons;
2000 Buttons << mbYes << mbNo;
2001 if(MessageDlg(
"Do you really want to clear all preferred directions?", mtWarning, Buttons, 0) == mrNo)
2017 catch(
const Exception &e)
2032 Screen->Cursor = TCursor(-11);
2041 Screen->Cursor = TCursor(-2);
2044 catch(
const Exception &e)
2062 catch(
const Exception &e)
2083 catch(
const Exception &e)
2108 catch(
const Exception &e)
2134 InfoPanel->Caption =
"PRE-START: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
2138 InfoPanel->Caption =
"OPERATING: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
2147 catch(
const Exception &e)
2174 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
2178 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
2187 catch(
const Exception &e)
2214 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
2218 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
2227 catch(
const Exception &e)
2260 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
2264 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
2273 catch(
const Exception &e)
2288 InfoPanel->Caption =
"ROUTE CANCELLING: Right click on truncate element, first element to cancel (anywhere else to skip)";
2295 catch(
const Exception &e)
2322 catch(
const Exception &e)
2337 UnicodeString MessageStr =
"Please note that the session will be lost if it hasn't been saved. Do you still wish to exit?";
2340 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
2379 catch(
const Exception &e)
2421 catch(
const Exception &e)
2434 Screen->Cursor = TCursor(-11);
2435 std::ifstream VecFile(LoadFileName.c_str());
2436 if(!(VecFile.fail()))
2441 bool GraphicsFollow =
false;
2460 TFont *TempFont =
new TFont;
2461 TempFont->Style.Clear();
2462 TempFont->Name =
"MS Sans Serif";
2463 TempFont->Size = 10;
2465 TempFont->Charset = (TFontCharset)(0);
2474 if((LeftExcess > 0) && (RightExcess > 0))
2478 else if((LeftExcess > 0) && (RightExcess <= 0))
2483 else if((LeftExcess <= 0) && (RightExcess > 0))
2495 if((TopExcess > 0) && (BotExcess > 0))
2499 else if((TopExcess > 0) && (BotExcess <= 0))
2504 else if((TopExcess <= 0) && (BotExcess > 0))
2521 if((LastChar ==
'y') || (LastChar ==
'Y'))
2525 ShowMessage(
"Railway not ready for operation so unable to load as a .rly file. Loading as a new railway under development");
2532 Screen->Cursor = TCursor(-2);
2567 ShowMessage(
"File open failed prior to load");
2569 Screen->Cursor = TCursor(-2);
2573 ShowMessage(
"File integrity check failed - unable to load " + LoadFileName +
". Please check that the file exists and is spelled correctly.");
2590 Screen->Cursor = TCursor(-11);
2592 if(!(VecFile.fail()))
2620 ShowMessage(
"File open failed prior to save");
2622 Screen->Cursor = TCursor(-2);
2627 catch(
const Exception &e)
2643 catch(
const Exception &e)
2660 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2664 Screen->Cursor = TCursor(-11);
2667 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2671 AnsiString ShortName =
"";
2672 for(
int x = ImageFileName.Length(); x > 0; x--)
2674 if(ImageFileName[x] ==
'\\')
2676 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2680 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2681 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2682 RailwayImage->PixelFormat = pf8bit;
2688 RailwayImage->Width = HPosMax - HPosMin;
2689 RailwayImage->Height = VPosMax - VPosMin;
2697 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2698 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2699 if(NewWidth > RailwayImage->Width)
2701 RailwayImage->Width = NewWidth;
2703 if(NewHeight > RailwayImage->Height)
2705 RailwayImage->Height = NewHeight;
2709 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2710 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2711 RailwayImage->Canvas->FillRect(Rect);
2718 RailwayImage->SaveToFile(ImageFileName);
2719 delete RailwayImage;
2722 Screen->Cursor = TCursor(-2);
2725 catch(
const Exception &e)
2727 if(e.Message.Pos(
"torage") > 0)
2729 Screen->Cursor = TCursor(-2);
2730 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2731 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2752 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2756 Screen->Cursor = TCursor(-11);
2759 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2763 AnsiString ShortName =
"";
2764 for(
int x = ImageFileName.Length(); x > 0; x--)
2766 if(ImageFileName[x] ==
'\\')
2768 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2772 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2773 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2774 RailwayImage->PixelFormat = pf8bit;
2779 RailwayImage->Width = HPosMax - HPosMin;
2780 RailwayImage->Height = VPosMax - VPosMin;
2788 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2789 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2790 if(NewWidth > RailwayImage->Width)
2792 RailwayImage->Width = NewWidth;
2794 if(NewHeight > RailwayImage->Height)
2796 RailwayImage->Height = NewHeight;
2800 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2801 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2802 RailwayImage->Canvas->FillRect(Rect);
2805 for(
int x = 0; x < ((RailwayImage->Width) / 16); x++)
2807 for(
int y = 0; y < ((RailwayImage->Height) / 16); y++)
2816 RailwayImage->SaveToFile(ImageFileName);
2817 delete RailwayImage;
2820 Screen->Cursor = TCursor(-2);
2823 catch(
const Exception &e)
2825 if(e.Message.Pos(
"torage") > 0)
2827 Screen->Cursor = TCursor(-2);
2828 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2829 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2849 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2853 Screen->Cursor = TCursor(-11);
2856 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2860 AnsiString ShortName =
"";
2861 for(
int x = ImageFileName.Length(); x > 0; x--)
2863 if(ImageFileName[x] ==
'\\')
2865 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2869 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2870 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2871 RailwayImage->PixelFormat = pf8bit;
2876 RailwayImage->Width = HPosMax - HPosMin;
2877 RailwayImage->Height = VPosMax - VPosMin;
2885 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2886 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2887 if(NewWidth > RailwayImage->Width)
2889 RailwayImage->Width = NewWidth;
2891 if(NewHeight > RailwayImage->Height)
2893 RailwayImage->Height = NewHeight;
2897 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2898 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2899 RailwayImage->Canvas->FillRect(Rect);
2906 RailwayImage->SaveToFile(ImageFileName);
2907 delete RailwayImage;
2910 Screen->Cursor = TCursor(-2);
2913 catch(
const Exception &e)
2915 if(e.Message.Pos(
"torage") > 0)
2917 Screen->Cursor = TCursor(-2);
2918 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2919 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2939 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2943 Screen->Cursor = TCursor(-11);
2948 TimetableTimeStr = TimetableTimeStr.SubString(1, 2) +
'.' + TimetableTimeStr.SubString(4, 2) +
'.' + TimetableTimeStr.SubString(7, 2);
2949 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2954 AnsiString ShortName =
"";
2955 for(
int x = ImageFileName.Length(); x > 0; x--)
2957 if(ImageFileName[x] ==
'\\')
2959 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2963 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2964 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2965 RailwayImage->PixelFormat = pf8bit;
2970 RailwayImage->Width = HPosMax - HPosMin;
2971 RailwayImage->Height = VPosMax - VPosMin;
2979 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2980 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2981 if(NewWidth > RailwayImage->Width)
2983 RailwayImage->Width = NewWidth;
2985 if(NewHeight > RailwayImage->Height)
2987 RailwayImage->Height = NewHeight;
2991 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2992 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2993 RailwayImage->Canvas->FillRect(Rect);
3007 bool BreakFlag =
false;
3033 RailwayImage->SaveToFile(ImageFileName);
3034 delete RailwayImage;
3037 Screen->Cursor = TCursor(-2);
3040 catch(
const Exception &e)
3042 if(e.Message.Pos(
"torage") > 0)
3044 Screen->Cursor = TCursor(-2);
3045 UnicodeString MessageStr =
"Insufficient memory available to store this image";
3046 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
3075 Screen->Cursor = TCursor(-11);
3077 if(!(VecFile.fail()))
3105 ShowMessage(
"Railway failed to save - can't open file");
3107 Screen->Cursor = TCursor(-2);
3111 catch(
const Exception &e)
3125 catch(
const Exception &e)
3147 catch(
const Exception &e)
3163 ShowMessage(
"Failed to find folder " +
FORMATTEDTT_DIR_NAME +
" in the folder where 'railway.exe' resides. Timetable can't be exported");
3171 Screen->Cursor = TCursor(-2);
3174 catch(
const Exception &e)
3234 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
3254 ActiveTrackElementNameMapEntry.second = 0;
3305 catch(
const Exception &e)
3354 if(TTBLFile.is_open())
3358 while(!TTBLFile.eof())
3361 if((c < 32) && (c != 13) && (c != 10) && (c !=
'\0'))
3363 ShowMessage(
"Timetable file is empty or contains non-ascii characters, codes must be between 20 and 127, or CR or LF");
3373 ShowMessage(
"Failed to open timetable file " +
CreateEditTTFileName +
", make sure it's spelled correctly, it exists and isn't open in another application");
3380 if(TTBLFile.is_open())
3389 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
3402 char *TimetableEntryString =
new char[10000];
3405 TTBLFile.getline(TimetableEntryString, 10000,
'\0');
3406 if(TTBLFile.eof() && (TimetableEntryString[0] ==
'\0'))
3412 AnsiString OneLine(TimetableEntryString);
3416 delete[]TimetableEntryString;
3421 ShowMessage(
"Failed to open timetable file " +
CreateEditTTFileName +
", make sure it's spelled correctly, it exists and isn't open in another application");
3457 ActiveTrackElementNameMapEntry.second = 0;
3483 catch(
const Exception &e)
3502 InfoPanel->Caption =
"Timetable mode: editor hidden";
3509 ShowHideTTButton->Hint =
"Hide the timetable editor to see the railway Shift H";
3514 catch(
const Exception &e)
3555 catch(
const Exception &e)
3596 catch(
const Exception &e)
3616 catch(
const Exception &e)
3629 bool ValidFlag =
true;
3650 TDateTime DummyTime;
3668 ShowMessage(
"One or more times excessive, not permitted to exceed 95 hours");
3672 AnsiString MinsStr = AnsiString(Mins), HrsStr = AnsiString(Hrs);
3675 MinsStr =
"0" + MinsStr;
3679 HrsStr =
"0" + HrsStr;
3683 NewString += HrsStr +
':' + MinsStr;
3700 catch(
const Exception &e)
3713 bool ValidFlag =
true;
3734 TDateTime DummyTime;
3752 ShowMessage(
"One or more times are now before 00:00, this is not permitted");
3756 AnsiString MinsStr = AnsiString(Mins), HrsStr = AnsiString(Hrs);
3759 MinsStr =
"0" + MinsStr;
3763 HrsStr =
"0" + HrsStr;
3767 NewString += HrsStr +
':' + MinsStr;
3783 catch(
const Exception &e)
3821 catch(
const Exception &e)
3866 if(OldVectorPos == 0)
3894 catch(
const Exception &e)
3953 catch(
const Exception &e)
3971 UnicodeString MessageStr =
"Are you sure this entry should be deleted?";
3972 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
4004 if(OldVectorPos == 0)
4032 catch(
const Exception &e)
4053 AnsiString TempStr =
"";
4054 bool ActiveLine =
false;
4079 while(TempStr[TempStr.Length()] ==
',')
4081 TempStr = TempStr.SubString(1, TempStr.Length() - 1);
4112 (*TTCurrentEntryPtr) = TempStr;
4182 catch(
const Exception &e)
4197 ShowMessage(
"Timetable is empty, can't save an empty timetable");
4201 std::ofstream TTBLFile;
4236 if(TTBLFile.is_open())
4240 TTBLFile << (*TEVPtr).c_str() <<
'\0';
4247 ShowMessage(
CreateEditTTFileName +
" failed to open, ensure not already open in another application");
4253 catch(
const Exception &e)
4268 ShowMessage(
"Timetable is empty, can't save an empty timetable");
4272 std::ofstream TTBLFile;
4281 for(
int x =
SaveTTDialog->FileName.Length(); x > 0; x--)
4299 if(TTBLFile.is_open())
4303 TTBLFile << (*TEVPtr).c_str() <<
'\0';
4310 ShowMessage(
CreateEditTTFileName +
" failed to open, ensure not already open in another application");
4316 catch(
const Exception &e)
4330 bool EndOfFile =
false;
4331 bool FinalCallFalse =
false;
4332 bool GiveMessagesTrue =
true;
4333 bool CheckLocationsExistInRailway =
false;
4336 CheckLocationsExistInRailway =
true;
4343 "The basic syntax seems OK but this check is very limited. Other aspects can only be checked by validating the whole timetable with the appropriate railway (.rly) loaded");
4349 catch(
const Exception &e)
4377 bool CheckLocationsExistInRailwayTrue =
true;
4380 Screen->Cursor = TCursor(-11);
4382 if(TTBLFile.is_open())
4388 ShowMessage(
"Timetable integrity OK");
4396 ShowMessage(
"Failed to open timetable file, make sure it's spelled correctly, it exists and isn't open in another application");
4398 Screen->Cursor = TCursor(-2);
4408 catch(
const Exception &e)
4432 AnsiString TempStr = *
TEVPtr;
4470 catch(
const Exception &e)
4494 AnsiString TempStr = *
TEVPtr;
4532 catch(
const Exception &e)
4569 catch(
const Exception &e)
4584 UnicodeString MessageStr =
"All changes to the timetable will be lost - proceed?";
4585 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
4595 if(TTBLFile.is_open())
4612 char *TimetableEntryString =
new char[10000];
4615 TTBLFile.getline(TimetableEntryString, 10000,
'\0');
4616 if(TTBLFile.eof() && (TimetableEntryString[0] ==
'\0'))
4622 AnsiString OneLine(TimetableEntryString);
4626 delete[]TimetableEntryString;
4631 ShowMessage(
"Failed to open timetable file, make sure it's spelled correctly, it exists and isn't open in another application");
4651 catch(
const Exception &e)
4666 ShowMessage(
"Failed to find folder " +
FORMATTEDTT_DIR_NAME +
" in the folder where 'railway.exe' resides. Timetable can't be exported");
4685 Screen->Cursor = TCursor(-2);
4690 catch(
const Exception &e)
4723 catch(
const Exception &e)
4738 UnicodeString MessageStr =
"The timetable has changed.\n\nAre you sure you want to exit without saving it?";
4739 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
4755 catch(
const Exception &e)
4783 catch(
const Exception &e)
4808 catch(
const Exception &e)
4826 catch(
const Exception &e)
4849 catch(
const Exception &e)
4901 catch(
const Exception &e)
4914 TrainController->
LogEvent(
"OAListBoxMouseUp," + AnsiString(X) +
"," + AnsiString(Y) +
"," + AnsiString(Button));
4916 int ScreenPosH, ScreenPosV;
4927 int HPos, VPos, TrainID = -1, TrackVectorPosition = -1;
4934 if(Button == mbLeft)
4940 bool ElementUnderOAPanel =
false;
4948 ElementUnderOAPanel =
true;
4951 bool ElementUnderPerformancePanel =
false;
4959 ElementUnderPerformancePanel =
true;
4966 !ElementUnderPerformancePanel && !ElementUnderOAPanel)
4985 TPoint MainScreenPoint(ScreenPosH + 8, ScreenPosV + 8);
4986 TPoint CursPos =
MainScreen->ClientToScreen(MainScreenPoint);
4987 Mouse->CursorPos = CursPos;
4995 catch(
const Exception &e)
5009 if(Button == mbRight)
5015 catch(
const Exception &e)
5031 if((TopPos + (Y / 13)) >=
OAListBox->Items->Count)
5039 std::advance(OACurrentEntryPtr, ((Y / 13) + TopPos));
5041 int TrainIDorTVPos = OACurrentEntryPtr->second.second;
5042 if(TrainIDorTVPos >= 0)
5048 TrainID = TrainIDorTVPos;
5059 TrackVectorPosition = -(TrainIDorTVPos + 1);
5071 PreStartTime, ActiveSegment, PostEnd
5085 Segment = PreStartTime;
5088 if(Segment == PreStartTime)
5095 Segment = ActiveSegment;
5106 AnsiString CurrentStr = *
TEVPtr;
5107 if(CurrentStr !=
"")
5109 CurrentStr = CurrentStr.SubString(1, 10);
5110 for(
int x = 1; x < CurrentStr.Length(); x++)
5112 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
5114 CurrentStr = CurrentStr.SubString(1, (x - 1));
5123 if(Segment == ActiveSegment)
5138 AnsiString Entry = *
TEVPtr;
5148 int SCPos = Entry.Pos(
';');
5149 int CPos = Entry.Pos(
',');
5156 if((CPos == 0) && (SCPos == 0))
5158 Entry = Entry.SubString(1, 12);
5160 else if((CPos > 0) && (SCPos > 0) && (CPos < SCPos))
5162 Entry = Entry.SubString(1, CPos - 1);
5164 else if((CPos > 0) && (SCPos > 0) && (CPos > SCPos))
5166 Entry = Entry.SubString(1, SCPos - 1);
5168 else if((CPos > 0) && (SCPos == 0))
5170 Entry = Entry.SubString(1, CPos - 1);
5174 Entry = Entry.SubString(1, SCPos - 1);
5187 if(Segment == PostEnd)
5195 AnsiString CurrentStr = *
TEVPtr;
5196 if(CurrentStr !=
"")
5198 CurrentStr = CurrentStr.SubString(1, 10);
5199 for(
int x = 1; x < CurrentStr.Length(); x++)
5201 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
5203 CurrentStr = CurrentStr.SubString(1, (x - 1));
5234 UnicodeString MessageStr =
5235 "If you wish to preserve the original order don't save any changes whilst in alphabetical order.\n\n" "To preserve the original order use alphabetical order to find the service required, click it to display it,"
5236 " then revert to the original order where the same service will be displayed and can be changed.";
5237 Application->MessageBox(MessageStr.c_str(), L
"Please Note:", MB_OK | MB_ICONWARNING);
5250 std::sort(SortStart, SortEnd);
5252 bool CurrentEntryChanged =
false;
5258 CurrentEntryChanged =
true;
5261 if(!CurrentEntryChanged)
5266 AZOrderButton->Hint = AnsiString(
"Arrange services in original order Toggle with Shift+ Z");
5272 UnicodeString MessageStr =
5273 "Reverting to the original order will discard any changes made whilst in alphabetical order.\n\nTo preserve the changes click 'No', then save the timetable or use 'save as' if you wish to keep the original timetable.\n\nDo you wish to proceed?";
5274 int button = Application->MessageBox(MessageStr.c_str(), L
"Warning!", MB_YESNO | MB_ICONWARNING);
5288 bool CurrentEntryChanged =
false;
5294 CurrentEntryChanged =
true;
5297 if(!CurrentEntryChanged)
5302 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
5311 catch(
const Exception &e)
5322 AnsiString OutStr =
"";
5325 while(x < ConvStr.Length())
5327 if((ConvStr[x] ==
'\r') && (ConvStr[x + 1] ==
'\n'))
5335 OutStr += ConvStr[x];
5339 if(x == ConvStr.Length())
5341 OutStr += ConvStr[x];
5347 while(OutStr[OutStr.Length()] ==
',')
5349 OutStr = OutStr.SubString(1, OutStr.Length() - 1);
5423 InfoPanel->Caption =
"Select option or change entry";
5437 bool ValidFlag =
true;
5438 for(
int x = 1; x <= AnsiAddSubText.Length(); x++)
5440 if((AnsiAddSubText[x] >
'9') || (AnsiAddSubText[x] <
'0'))
5448 if(AnsiAddSubText.ToInt() != 0)
5521 bool ServiceEntry =
true;
5526 bool ServiceEntry =
false;
5538 InfoPanel->Caption =
"Add or change entry then save it, or cancel";
5548 AnsiString((
short)ServiceEntry));
5555 int CommaPos = Data.Pos(
',');
5556 if((CommaPos == 0) && (Data !=
""))
5558 CommaPos = Data.Length() + 1;
5561 if(Data.Length() <= CommaPos)
5565 Data = Data.SubString(CommaPos + 1, Data.Length() - CommaPos);
5604 if(CurrentStr !=
"")
5606 for(
int x = 1; x < CurrentStr.Length(); x++)
5608 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
5610 CurrentStr = CurrentStr.SubString(1, (x - 1));
5643 TDateTime DummyTime;
5644 bool TimesPresent =
false;
5652 TimesPresent =
true;
5661 return(TimesPresent);
5688 UnicodeString MessageStr =
"The railway has changed, exit without saving?";
5689 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
5701 Application->Terminate();
5703 catch(
const Exception &e)
5726 catch(
const Exception &e)
5749 catch(
const Exception &e)
5772 catch(
const Exception &e)
5849 catch(
const Exception &e)
5867 catch(
const Exception &e)
5886 catch(
const Exception &e)
5930 catch(
const Exception &e)
5941 TrainController->
LogEvent(
"MainScreenMouseDown2," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
5943 "," + AnsiString(Y));
5955 int NoOffsetX, NoOffsetY;
5957 if(Button == mbRight)
5961 AnsiString Text =
"";
5970 Screen->Cursor = TCursor(-22);
6026 bool TrackEraseSuccessfulFlag;
6027 int ErasedTrackVectorPosition;
6028 Screen->Cursor = TCursor(-11);
6030 if(TrackEraseSuccessfulFlag)
6032 if(ErasedTrackVectorPosition > -1)
6065 Screen->Cursor = TCursor(-2);
6073 bool LeadingPointsAtLastElement =
false;
6088 if(!LeadingPointsAtLastElement)
6093 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
6112 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Can't end on leading points, continue or truncate";
6193 if((TrainID01 > -1) && (TrainID23 > -1))
6283 AnsiString LocName =
"";
6288 if((LocName ==
"") && (Train.
MidElement > -1))
6446 Screen->Cursor = TCursor(-11);
6457 Screen->Cursor = TCursor(-2);
6533 Screen->Cursor = TCursor(-11);
6535 bool TrackLinkingRequiredFlag;
6537 TSpeedButton *TempSpeedButton = 0;
6547 bool InternalChecks =
true;
6555 if(TrackLinkingRequiredFlag)
6584 Screen->Cursor = TCursor(-2);
6598 NewGI.
Width = UGMIt->second->Width;
6599 NewGI.
Height = UGMIt->second->Height;
6625 AnsiString NameString;
6635 unsigned int ValidPosition;
6646 ValidElement = InactiveTrackElement1;
6647 ValidPosition = InactivePair.first;
6652 ValidElement = InactiveTrackElement2;
6653 ValidPosition = InactivePair.second;
6664 InfoPanel->Caption =
"NAMING LOCATIONS: Enter name, 'Carriage Return' to accept, 'Escape' to quit";
6695 bool FinishElement =
false, LeadingPointsAtLastElement =
false;
6696 Screen->Cursor = TCursor(-11);
6711 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Set values (overall length), or right click to cancel/truncate";
6725 Screen->Cursor = TCursor(-2);
6731 if(!LeadingPointsAtLastElement)
6736 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
6757 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Can't end on leading points, need to continue or truncate";
6772 Screen->Cursor = TCursor(-2);
6777 Screen->Cursor = TCursor(-2);
6795 InfoPanel->Caption =
"CONNECTING GAPS: Connecting element selected";
6807 ShowMessage(
"All gaps set");
6835 int TrueX = 0, TrueY = 0;
6836 AnsiString ExistingText =
"";
6838 TFont *ExistingTextFont =
new TFont;
6839 int ExistingTextHPos = 0, ExistingTextVPos = 0;
6845 if((TrueX >= TextPtr->HPos) && (TrueX < (TextPtr->HPos + abs(TextPtr->Font->Height))) && (TrueY >= TextPtr->VPos) && (TrueY <
6846 (TextPtr->VPos + abs(TextPtr->Font->Height))))
6848 ExistingText = TextPtr->TextString;
6849 ExistingTextFont->Assign(TextPtr->Font);
6850 ExistingTextHPos = TextPtr->HPos;
6851 ExistingTextVPos = TextPtr->VPos;
6864 TextBox->Font->Assign(ExistingTextFont);
6866 Text_X = ExistingTextHPos;
6867 Text_Y = ExistingTextVPos;
6885 TextBox->Text =
"New Text: CR=end, ESC=quit";
6889 delete ExistingTextFont;
6991 Screen->Cursor = TCursor(-11);
7002 ShowMessage(
"Preferred direction added");
7006 Screen->Cursor = TCursor(-2);
7025 Screen->Cursor = TCursor(-2);
7029 Screen->Cursor = TCursor(-2);
7126 AnsiString(PDE.
VLoc));
7140 bool PointsChanged =
false;
7141 IDInt ReqPosRouteID(-1);
7143 bool CallonTrue =
true;
7151 ReqPosRouteID, PointsChanged))
7193 float TempSpeedVal = 1;
7263 int DivergingPosition = TrackElement.
Conn[3];
7265 DivergingPosition)))
7294 bool TrainPresent =
false;
7298 int BDVectorPos = -1;
7308 TDateTime TempExcessLCDownTime;
7319 if(TempExcessLCDownTime > TDateTime(0))
7349 AnsiString Message =
7350 AnsiString(
"This will open the level crossing manually (it will show in green).\n\nA manually opened"
7351 " level crossing must be manually closed, and as soon as possible to avoid time penalties.\n\n" "This message will not be shown again."
7396 InfoPanel->Caption =
"PRE-START: Select next route location";
7400 InfoPanel->Caption =
"OPERATING: Select next route location";
7413 bool CallonFalse =
false;
7421 InfoPanel->Caption =
"PRE-START: Select next route location";
7425 InfoPanel->Caption =
"OPERATING: Select next route location";
7447 Screen->Cursor = TCursor(-11);
7449 bool PointsChanged =
false;
7459 float TempSpeedVal = 1;
7468 else if(PointsChanged)
7483 Screen->Cursor = TCursor(-2);
7491 bool CallonFalse =
false;
7496 float TempSpeedVal = 1;
7505 else if(PointsChanged)
7523 Screen->Cursor = TCursor(-2);
7531 catch(
const Exception &e)
7545 TrainController->
LogEvent(
"MainScreenMouseDown3," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
7547 "," + AnsiString(Y));
7548 if(Button != mbLeft)
7554 Screen->Cursor = TCursor(-22);
7560 int HRounding, VRounding;
7633 else if(TempLevel2OperMode ==
Operating)
7636 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
7640 else if(TempLevel2OperMode ==
Paused)
7643 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
7649 else if(TempLevel2OperMode ==
PreStart)
7652 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
7663 catch(
const Exception &e)
7764 if(CurrentHLoc >= StartHLoc)
7772 if(CurrentVLoc >= StartVLoc)
7796 TRect TempRect(StartHLoc, StartVLoc, CurrentHLoc, CurrentVLoc);
7814 if(CurrentHLoc >= StartHLoc)
7822 if(CurrentVLoc >= StartVLoc)
7846 TRect TempRect(StartHLoc, StartVLoc, CurrentHLoc, CurrentVLoc);
7925 catch(
const Exception &e)
7961 TrainController->
LogEvent(
"MainScreenMouseUp," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
7964 Screen->Cursor = TCursor(-2);
7974 Screen->Cursor = TCursor(-11);
7979 if(EndHLoc >= StartHLoc)
7987 if(EndVLoc >= StartVLoc)
7995 if(StartHLoc >= EndHLoc)
8005 if(StartVLoc >= EndVLoc)
8042 Screen->Cursor = TCursor(-2);
8114 if(IATVecPair.second != IATVecPair.first)
8124 int PrefDirPos0, PrefDirPos1, PrefDirPos2, PrefDirPos3;
8134 if(PrefDirPos0 > -1)
8139 if(PrefDirPos1 > -1)
8144 if(PrefDirPos2 > -1)
8149 if(PrefDirPos3 > -1)
8168 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
8176 bool SelectVectorNamedElement =
false;
8177 AnsiString SelectTextString;
8182 SelectVectorNamedElement =
true;
8186 if(SelectVectorNamedElement)
8188 SelectTextString =
"##**" + TextPtr->TextString;
8192 SelectTextString = TextPtr->TextString;
8194 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
8203 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
8206 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) &&
8207 (UserGraphicPtr->VPos >= LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
8220 Screen->Cursor = TCursor(-2);
8226 Screen->Cursor = TCursor(-11);
8232 if(EndHLoc >= StartHLoc)
8240 if(EndVLoc >= StartVLoc)
8248 if(StartHLoc >= EndHLoc)
8258 if(StartVLoc >= EndVLoc)
8291 Screen->Cursor = TCursor(-2);
8323 Screen->Cursor = TCursor(-2);
8348 catch(
const Exception &e)
8385 throw Exception(
"Warning - Utilities->CallLog contains more than 50 items");
8443 catch(
const Exception &e)
8619 if(
WholeRailwayMoving && (GetAsyncKeyState(VK_LBUTTON) >= 0) && (GetAsyncKeyState(VK_RBUTTON) >= 0))
8622 Screen->Cursor = TCursor(-2);
8647 bool TrainPresent =
false;
8664 TDateTime TempExcessLCDownTime;
8673 if(TempExcessLCDownTime > TDateTime(0))
8702 bool ElementRemovedFlag =
false;
8719 int RouteNumber1, RouteNumber2, TrainID;
8727 ElementRemovedFlag =
true;
8744 bool WH1 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog1->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog1->Width +
OutputLog1->Left))
8747 bool WH2 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog2->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog2->Width +
OutputLog2->Left))
8750 bool WH3 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog3->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog3->Width +
OutputLog3->Left))
8753 bool WH4 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog4->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog4->Width +
OutputLog4->Left))
8756 bool WH5 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog5->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog5->Width +
OutputLog5->Left))
8759 bool WH6 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog6->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog6->Width +
OutputLog6->Left))
8762 bool WH7 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog7->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog7->Width +
OutputLog7->Left))
8765 bool WH8 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog8->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog8->Width +
OutputLog8->Left))
8768 bool WH9 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog9->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog9->Width +
OutputLog9->Left))
8771 bool WH10 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog10->Left) &&
8775 if(WH1 || WH2 || WH3 || WH4 || WH5 || WH6 || WH7 || WH8 || WH9 || WH10 ||
SkipTTActionsListBox->Visible)
8795 AnsiString Type[15] =
8797 "Simple",
"Crossover",
"Points",
"Buffers",
"Bridge",
"SignalPost",
"Continuation",
"Platform",
"GapJump",
"FootCrossing",
"Unused",
"Concourse",
8798 "Parapet",
"NamedNonStationLocation",
"Erase"
8801 int ScreenX = Mouse->CursorPos.x -
MainScreen->ClientOrigin.x;
8802 int ScreenY = Mouse->CursorPos.y -
MainScreen->ClientOrigin.y;
8804 AnsiString MouseStr =
"Posx: " + AnsiString(ScreenX) +
"; Posy: " + AnsiString(ScreenY);
8809 DevelopmentPanel->Caption = MouseStr +
"; TVPos: " + AnsiString(Position) +
"; H: " + AnsiString(HLoc) +
"; V: " + AnsiString(VLoc) +
8810 "; SpTg: " + AnsiString(TrackElement.
SpeedTag) +
"; Type: " + Type[TrackElement.
TrackType] +
"; Att: " + AnsiString(TrackElement.
Attribute)
8831 if((GetKeyState(VK_LBUTTON) >= 0) && (GetKeyState(VK_RBUTTON) >= 0) && (
TTCurrentEntryPtr > 0))
8961 Screen->Cursor = TCursor(-11);
8984 ExitPair.first = -1;
8985 ExitPair.second = -1;
9156 int RouteStartVecPos;
9172 if(FoundFlag && (RouteStartVecPos > -1))
9188 catch(
const EIdException &e)
9194 catch(
const Exception &e)
9212 InfoPanel->Caption =
"CALLING ON: Select signal for call on";
9226 catch(
const Exception &e)
9240 Screen->Cursor = TCursor(-11);
9284 Screen->Cursor = TCursor(-2);
9287 catch(
const Exception &e)
9301 Screen->Cursor = TCursor(-11);
9345 Screen->Cursor = TCursor(-2);
9348 catch(
const Exception &e)
9362 Screen->Cursor = TCursor(-11);
9407 Screen->Cursor = TCursor(-2);
9410 catch(
const Exception &e)
9424 Screen->Cursor = TCursor(-11);
9468 Screen->Cursor = TCursor(-2);
9471 catch(
const Exception &e)
9485 Screen->Cursor = TCursor(-11);
9526 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
9533 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
9542 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
9569 if((LeftExcess > 0) && (RightExcess > 0))
9573 else if((LeftExcess > 0) && (RightExcess <= 0))
9578 else if((LeftExcess <= 0) && (RightExcess > 0))
9590 if((TopExcess > 0) && (BotExcess > 0))
9594 else if((TopExcess > 0) && (BotExcess <= 0))
9599 else if((TopExcess <= 0) && (BotExcess > 0))
9615 ZoomButton->Glyph->LoadFromResourceName(0,
"ZoomIn");
9617 Screen->Cursor = TCursor(-2);
9621 catch(
const Exception &e)
9635 Screen->Cursor = TCursor(-11);
9660 Screen->Cursor = TCursor(-2);
9664 catch(
const Exception &e)
9692 catch(
const Exception &e)
9708 catch(
const Exception &e)
9729 ShowMessage(
"Please be aware when pasting that anything inside the pasted area will be overwritten.\n\nThis warning will not be shown again.");
9740 catch(
const Exception &e)
9762 TRect NewSelectRect(TLHCH, TLHCV, BRHCH, BRHCV);
9800 catch(
const Exception &e)
9821 catch(
const Exception &e)
9842 catch(
const Exception &e)
9880 int FlipLinkArray[10] =
9882 0, 7, 8, 9, 4, 5, 6, 1, 2, 3
9903 bool ELinkPosFound =
false, XLinkPosFound =
false;
9904 for(
int y = 0; y < 4; y++)
9906 if(!ELinkPosFound && (PDE.
Link[y] == ELink))
9909 ELinkPosFound =
true;
9911 if(!XLinkPosFound && (PDE.
Link[y] == XLink))
9914 XLinkPosFound =
true;
9923 bool FoundFlag =
false;
9930 if(!PDE.
EntryExitNumber() || !ELinkPosFound || !XLinkPosFound || !FoundFlag)
9933 ShowMessage(
"Unable to re-orientate the preferred directions, these won't be set in the rotated selection");
9952 int MidVPosAfterFlip = ((VerSum * 16) + 15) - MidVPosBeforeFlip;
9960 catch(
const Exception &e)
9998 int MirrorLinkArray[10] =
10000 0, 3, 2, 1, 6, 5, 4, 9, 8, 7
10021 bool ELinkPosFound =
false, XLinkPosFound =
false;
10022 for(
int y = 0; y < 4; y++)
10024 if(!ELinkPosFound && (PDE.
Link[y] == ELink))
10027 ELinkPosFound =
true;
10029 if(!XLinkPosFound && (PDE.
Link[y] == XLink))
10032 XLinkPosFound =
true;
10040 bool FoundFlag =
false;
10047 if(!PDE.
EntryExitNumber() || !ELinkPosFound || !XLinkPosFound || !FoundFlag)
10050 ShowMessage(
"Unable to re-orientate the preferred directions, these won't be set in the rotated selection");
10069 int MidHPosAfterMirror = ((HorSum * 16) + 15) - MidHPosBeforeMirror;
10071 if(LeftPosAfterMirror < (
SelectRect.left * 16))
10081 catch(
const Exception &e)
10123 int Rot180LinkArray[10] =
10125 0, 9, 8, 7, 6, 5, 4, 3, 2, 1
10145 bool ELinkPosFound =
false, XLinkPosFound =
false;
10146 for(
int y = 0; y < 4; y++)
10148 if(!ELinkPosFound && (PDE.
Link[y] == ELink))
10151 ELinkPosFound =
true;
10153 if(!XLinkPosFound && (PDE.
Link[y] == XLink))
10156 XLinkPosFound =
true;
10164 bool FoundFlag =
false;
10171 if(!PDE.
EntryExitNumber() || !ELinkPosFound || !XLinkPosFound || !FoundFlag)
10174 ShowMessage(
"Unable to re-orientate the preferred directions, these won't be set in the rotated selection");
10194 int MidVPosAfterFlip = ((VerSum * 16) + 15) - MidVPosBeforeFlip;
10206 int MidHPosAfterMirror = ((HorSum * 16) + 15) - MidHPosBeforeMirror;
10208 if(LeftPosAfterMirror < (
SelectRect.left * 16))
10220 catch(
const Exception &e)
10233 Screen->Cursor = TCursor(-11);
10250 int button = Application->MessageBox
10251 (L
"Original selection adjusted to make it square. 'OK' to keep this selection or 'Cancel' to make a new selection",
10252 L
"Left click and hold here to move this message box", MB_OKCANCEL);
10253 if(button == IDCANCEL)
10261 Screen->Cursor = TCursor(-2);
10301 if(IATVecPair.second != IATVecPair.first)
10311 int PrefDirPos0, PrefDirPos1, PrefDirPos2, PrefDirPos3;
10321 if(PrefDirPos0 > -1)
10326 if(PrefDirPos1 > -1)
10331 if(PrefDirPos2 > -1)
10336 if(PrefDirPos3 > -1)
10349 int HighSelectVPos =
SelectRect.bottom * 16;
10355 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos < HighSelectVPos))
10362 bool SelectVectorNamedElement =
false;
10363 AnsiString SelectTextString;
10368 SelectVectorNamedElement =
true;
10372 if(SelectVectorNamedElement)
10374 SelectTextString =
"##**" + TextPtr->TextString;
10378 SelectTextString = TextPtr->TextString;
10380 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
10390 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
10393 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) && (UserGraphicPtr->VPos >=
10394 LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
10420 int RotRightLinkArray[10] =
10422 0, 3, 6, 9, 2, 5, 8, 1, 4, 7
10442 bool ELinkPosFound =
false, XLinkPosFound =
false;
10443 for(
int y = 0; y < 4; y++)
10445 if(!ELinkPosFound && (PDE.
Link[y] == ELink))
10448 ELinkPosFound =
true;
10450 if(!XLinkPosFound && (PDE.
Link[y] == XLink))
10453 XLinkPosFound =
true;
10461 bool FoundFlag =
false;
10468 if(!PDE.
EntryExitNumber() || !ELinkPosFound || !XLinkPosFound || !FoundFlag)
10471 ShowMessage(
"Unable to re-orientate the preferred directions, these won't be set in the rotated selection");
10493 int MidHPosAfterRotate = ((
SelectRect.bottom * 16) - 1) + (
SelectRect.left * 16) - MidVPosBeforeRotate;
10500 Screen->Cursor = TCursor(-2);
10505 catch(
const Exception &e)
10519 Screen->Cursor = TCursor(-11);
10536 int button = Application->MessageBox
10537 (L
"Original selection adjusted to make it square. 'OK' to keep this selection or 'Cancel' to make a new selection",
10538 L
"Left click and hold here to move this message box", MB_OKCANCEL);
10539 if(button == IDCANCEL)
10547 Screen->Cursor = TCursor(-2);
10587 if(IATVecPair.second != IATVecPair.first)
10597 int PrefDirPos0, PrefDirPos1, PrefDirPos2, PrefDirPos3;
10607 if(PrefDirPos0 > -1)
10612 if(PrefDirPos1 > -1)
10617 if(PrefDirPos2 > -1)
10622 if(PrefDirPos3 > -1)
10635 int HighSelectVPos =
SelectRect.bottom * 16;
10641 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos < HighSelectVPos))
10648 bool SelectVectorNamedElement =
false;
10649 AnsiString SelectTextString;
10654 SelectVectorNamedElement =
true;
10658 if(SelectVectorNamedElement)
10660 SelectTextString =
"##**" + TextPtr->TextString;
10664 SelectTextString = TextPtr->TextString;
10666 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
10676 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
10679 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) && (UserGraphicPtr->VPos >=
10680 LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
10706 int RotLeftLinkArray[10] =
10708 0, 7, 4, 1, 8, 5, 2, 9, 6, 3
10728 bool ELinkPosFound =
false, XLinkPosFound =
false;
10729 for(
int y = 0; y < 4; y++)
10731 if(!ELinkPosFound && (PDE.
Link[y] == ELink))
10734 ELinkPosFound =
true;
10736 if(!XLinkPosFound && (PDE.
Link[y] == XLink))
10739 XLinkPosFound =
true;
10747 bool FoundFlag =
false;
10754 if(!PDE.
EntryExitNumber() || !ELinkPosFound || !XLinkPosFound || !FoundFlag)
10757 ShowMessage(
"Unable to re-orientate the preferred directions, these won't be set in the rotated selection");
10780 int MidVPosAfterRotate = ((
SelectRect.bottom * 16) - 1) + (
SelectRect.left * 16) - MidHPosBeforeRotate;
10786 Screen->Cursor = TCursor(-2);
10791 catch(
const Exception &e)
10811 catch(
const Exception &e)
10830 catch(
const Exception &e)
10848 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Set values or leave blank for no change";
10851 ShowMessage(
"Note: length value will apply to each element's track within the selection.\n\nThis message will not be shown again.");
10861 catch(
const Exception &e)
10879 bool FoundFlag =
false;
10923 catch(
const Exception &e)
10955 Clipboard()->Clear();
10956 Clipboard()->Close();
10959 catch(
const EClipboardException &e)
10965 catch(
const Exception &e)
10985 UnicodeString CountWord =
"There are several track elements without preferred directions.\n\n"
10986 "Do you wish to highlight them (YES) or skip this part of the check (NO)?";
10988 int PD0, PD1, PD2, PD3, HLoc, VLoc, LastHLoc = -2000000, LastVLoc = -2000000;
10989 AnsiString TempInfo =
InfoPanel->Caption;
10992 ShowMessage(
"No preferred directions set.");
10999 InfoPanel->Caption =
"Checking preferred directions - please wait";
11002 LasTHVShortPair.first = -2000000;
11003 LasTHVShortPair.second = -2000000;
11004 Screen->Cursor = TCursor(-11);
11009 bool ELinkFound =
false;
11098 if((LastHLoc != HLoc) || (LastVLoc != VLoc))
11120 Screen->Cursor = TCursor(-2);
11121 int Button = Application->MessageBox(L
"Preferred direction missing or a mismatch at a link\n"
11122 "between the highlighted element and an adjacent element.\n\n"
11123 "The highlighted element may be behind this message\n"
11124 "which can be moved by left clicking the mouse in the\n"
11125 "title bar and dragging it.\n\n"
11126 "The omission/mismatch may or may not matter depending\n"
11127 "on routing requirements during operation.\n\n"
11128 "Click 'OK' to ignore and continue checking or 'Cancel'\n"
11129 "to allow correction.", L
"Warning", MB_OKCANCEL | MB_ICONWARNING);
11131 if(Button == IDCANCEL)
11137 Screen->Cursor = TCursor(-11);
11142 bool XLinkFound =
false;
11215 if((LastHLoc != HLoc) || (LastVLoc != VLoc))
11237 Screen->Cursor = TCursor(-2);
11238 int Button = Application->MessageBox(L
"Preferred direction missing or a mismatch at a link\n"
11239 "between the highlighted element and an adjacent element.\n\n"
11240 "The highlighted element may be behind this message\n"
11241 "which can be moved by left clicking the mouse in the\n"
11242 "title bar and dragging it.\n\n"
11243 "The omission/mismatch may or may not matter depending\n"
11244 "on routing requirements during operation.\n\n"
11245 "Click 'OK' to ignore and continue checking or 'Cancel'\n"
11246 "to allow correction.", L
"Warning", MB_OKCANCEL | MB_ICONWARNING);
11248 if(Button == IDCANCEL)
11254 Screen->Cursor = TCursor(-11);
11296 CountWord =
"There are many track elements without preferred directions.\n\n"
11297 "Do you wish to highlight them (YES) or skip this part of the check (NO)?";
11301 Screen->Cursor = TCursor(-2);
11302 int Button = Application->MessageBox(CountWord.c_str(), L
"Skip option", MB_YESNO);
11310 Screen->Cursor = TCursor(-11);
11326 if((LastHLoc != HLoc) || (LastVLoc != VLoc))
11348 Screen->Cursor = TCursor(-2);
11349 int Button = Application->MessageBox(L
"Preferred direction mismatch at a link between the\n"
11350 "highlighted element and an adjacent element.\n\n"
11351 "The highlighted element may be behind this message\n"
11352 "which can be moved by left clicking the mouse in the\n"
11353 "title bar and dragging it.\n\n"
11354 "The mismatch may or may not matter depending on\n"
11355 "routing requirements during operation.\n\n"
11356 "Click 'OK' to ignore and continue checking or 'Cancel'\n"
11357 "to allow correction.", L
"Warning", MB_OKCANCEL | MB_ICONWARNING);
11359 if(Button == IDCANCEL)
11365 Screen->Cursor = TCursor(-11);
11376 if((LastHLoc != HLoc) || (LastVLoc != VLoc))
11398 Screen->Cursor = TCursor(-2);
11399 int Button = Application->MessageBox(L
"Preferred direction mismatch at a link between the\n"
11400 "highlighted element and an adjacent element.\n\n"
11401 "The highlighted element may be behind this message\n"
11402 "which can be moved by left clicking the mouse in the\n"
11403 "title bar and dragging it.\n\n"
11404 "The mismatch may or may not matter depending on\n"
11405 "routing requirements during operation.\n\n"
11406 "Click 'OK' to ignore and continue checking or 'Cancel'\n"
11407 "to allow correction.", L
"Warning", MB_OKCANCEL | MB_ICONWARNING);
11409 if(Button == IDCANCEL)
11415 Screen->Cursor = TCursor(-11);
11422 Screen->Cursor = TCursor(-2);
11423 ShowMessage(
"Finished");
11427 catch(
const Exception &e)
11429 Screen->Cursor = TCursor(-2);
11430 ShowMessage(
"Error in preferred direction checking, unable to complete the check");
11445 int PD0 = -1, PD1 = -1, PD2 = -1, PD3 = -1;
11446 int PDLinked0 = -1, PDLinked1 = -1, PDLinked2 = -1, PDLinked3 = -1;
11447 int BidirLinkPos = -1;
11448 bool FoundFlag =
false, BidirOnLink =
false;
11450 if((PD0 == -1) || (PD2 == -1) || (PD3 > -1))
11525 if((BidirLinkPos == -1) || (BidirLinkPos > 3))
11538 if((TVLinkPos == 0) || (TVLinkPos == 2) || (TVLinkPos > 3))
11548 if((TVLinkPos != 1) && (TVLinkPos != 3))
11560 if((PDLinked0 == -1) || (PDLinked2 == -1) || (PDLinked3 > -1))
11571 BidirOnLink =
true;
11575 BidirOnLink =
true;
11584 BidirOnLink =
true;
11588 BidirOnLink =
true;
11597 BidirOnLink =
true;
11601 BidirOnLink =
true;
11640 bool CheckLocationsExistInRailwayTrue =
true;
11644 Screen->Cursor = TCursor(-11);
11645 std::ifstream TTBLFile(AnsiString(
TimetableDialog->FileName).c_str(), std::ios_base::binary);
11646 if(TTBLFile.is_open())
11648 bool SessionFileFalse =
false;
11657 ShowMessage(
"Failed to open timetable file, make sure it's spelled correctly, it exists and isn't open in another application");
11659 Screen->Cursor = TCursor(-2);
11663 ShowMessage(
"Timetable integrity check failed - unable to load " +
TimetableDialog->FileName +
". Please check that the file exists and is spelled correctly.");
11670 catch(
const Exception &e)
11697 AnsiString LocName =
"";
11702 if((LocName ==
"") && (Train.
MidElement > -1))
11720 if((NextElementPosition > -1) && (NextEntryPos > -1))
11736 if((LocName ==
"") && (Train.
MidElement > -1))
11743 catch(
const Exception &e)
11777 if((LeadElementLocName ==
"") && (MidElementLocName ==
"") && (Train.
LeadElement > -1))
11781 if((MidElementLocName ==
"") && (Train.
MidElement > -1))
11785 if((LeadElementLocName == RequiredLocName) || (MidElementLocName == RequiredLocName))
11787 LocName = RequiredLocName;
11789 else if(LeadElementLocName !=
"")
11791 LocName = LeadElementLocName;
11793 else if(MidElementLocName !=
"")
11795 LocName = MidElementLocName;
11834 int NextElementPos = -1;
11835 int NextEntryPos = -1;
11854 if((NextElementPos > -1) && (NextEntryPos > -1))
11888 catch(
const Exception &e)
11906 AnsiString LocName =
"";
11911 if((LocName ==
"") && (Train.
MidElement > -1))
11919 if((LocName ==
"") && (Train.
MidElement > -1))
11926 catch(
const Exception &e)
11956 int NextElementPos = -1;
11957 int NextEntryPos = -1;
11965 if((NextElementPos > -1) && (NextEntryPos > -1))
11985 catch(
const Exception &e)
11999 TTrain *TrainToBeJoinedBy;
12012 ShowMessage(
"Can't join two trains when both are without power");
12016 AnsiString TrainToBeJoinedByHeadCode = TrainToBeJoinedBy->
HeadCode;
12018 double OtherBrakeForce = TrainToBeJoinedBy->
MaxBrakeRate * TrainToBeJoinedBy->
Mass;
12020 double CombinedBrakeRate = (OtherBrakeForce + OwnBrakeForce) / (TrainToBeJoinedBy->
Mass + ThisTrain.
Mass);
12027 ThisTrain.
Mass += TrainToBeJoinedBy->
Mass;
12034 AnsiString LocName =
"";
12039 if((LocName ==
"") && (ThisTrain.
MidElement > -1))
12043 if((LocName ==
"") && ThisTrain.
LeadElement > -1)
12047 if((LocName ==
"") && (ThisTrain.
MidElement > -1))
12081 catch(
const Exception &e)
12112 AnsiString LocName =
"";
12117 if((LocName ==
"") && (Train.
MidElement > -1))
12125 if((LocName ==
"") && (Train.
MidElement > -1))
12141 catch(
const Exception &e)
12173 AnsiString OneLine;
12175 int NewLinePos = TTStr.Pos(
'\n');
12178 for(
int x = 0; x < 30; x++)
12180 if((TTStr.Length() > 1) && (NewLinePos <= TTStr.Length()) && (NewLinePos != 0))
12182 OneLine = TTStr.SubString(1, NewLinePos);
12189 TTStr = TTStr.SubString(NewLinePos + 1, TTStr.Length() - NewLinePos - 1);
12190 NewLinePos = TTStr.Pos(
'\n');
12192 else if((TTStr.Length() > 1) && (NewLinePos == 0) && ((TTStr.SubString(3, 1) ==
':') || (TTStr.SubString(1, 5) ==
"Termi")))
12199 if(TTStr.Length() <2)
12203 AnsiString EndStr = OneLine.SubString(8, 5);
12205 if((EndStr ==
"Form ") || (EndStr ==
"Join ") || (EndStr ==
"Exit "))
12212 ShowMessage(
"No timetabled events");
12239 catch(
const Exception &e)
12248 TShiftState Shift,
int X,
int Y)
12273 int Count = 0, PassNum = 0, SkippedEvents = 0;
12276 ShowMessage(
"This is already the next event, nothing will be skipped");
12282 if((AVEPtr->FormatType ==
TimeTimeLoc) && (AVEPtr->ArrivalTime != AVEPtr->DepartureTime))
12291 if((AVEPtr->Command ==
"cdt") || (AVEPtr->Command ==
"pas") || ((AVEPtr->FormatType ==
TimeLoc) && (AVEPtr->DepartureTime != TDateTime(-1))))
12302 if((StartStr !=
"Arri") && (StartStr !=
"Pass") && (StartStr !=
"Exit"))
12304 ShowMessage(
"When stopped at a signal the selected next event must be 'Arrive...', 'Pass...', or 'Exit railway...'");
12309 int button = Application->MessageBox(L
"This will skip all events before the selection,\n\nOK to proceed?", L
"", MB_YESNO);
12310 if(button == IDYES)
12313 if(SkipTTLBString[SkipTTLBString.Length()] ==
'\n')
12315 SkipTTLBString = SkipTTLBString.SubString(1, (SkipTTLBString.Length() - 1));
12319 +
" timetabled events skipped until " + SkipTTLBString;
12331 int Count = 0, PassNum = 0, SkippedEvents = 0;
12336 ShowMessage(
"This is already the next event, nothing will be skipped");
12342 if(AVEPtr->DepartureTime > TDateTime(0))
12359 if((AVEPtr->Command ==
"cdt") || (AVEPtr->Command ==
"pas") || ((AVEPtr->FormatType ==
TimeLoc) && (AVEPtr->DepartureTime > TDateTime(0))))
12378 ShowMessage(
"When stopped at a location the selected next event must either occur at the same location or be 'Arrive...', 'Pass...', or 'Exit railway...'");
12389 UnicodeString Message =
"This will skip all events before the selection.\n\nOK to proceed?";
12392 Message =
"This will skip all events between the departure and the selection.\n\n"
12393 "Note that no more events may be skipped for this train until after\n"
12394 "it departs from the current location\n\nOK to proceed?";
12396 int button = Application->MessageBox(Message.c_str(), L
"", MB_YESNO);
12397 if(button == IDYES)
12401 if(SkipTTLBString[SkipTTLBString.Length()] ==
'\n')
12403 SkipTTLBString = SkipTTLBString.SubString(1, (SkipTTLBString.Length() - 1));
12420 +
" timetabled events skipped after the departure until " + SkipTTLBString;
12436 catch(
const Exception &e)
12485 catch(
const Exception &e)
12503 while((NewServiceActionEntryPtr->
Command !=
"Fns") && (NewServiceActionEntryPtr->
Command !=
"Fns-sh") && (NewServiceActionEntryPtr->
Command !=
"F-nshs"))
12505 NewServiceActionEntryPtr++;
12508 ShowMessage(
"No follow-on service found, option unavailable");
12515 UnicodeString MessageStr =
"This action will skip all timetabled events until follow-on service " + Train.
FollowOnServiceRef +
" reaches this location\n\nOK to proceed?";
12516 if(NewServiceActionEntryPtr->
Command ==
"Fns")
12520 int button = Application->MessageBox(MessageStr.c_str(), L
"", MB_YESNO);
12532 else if(NewServiceActionEntryPtr->
Command ==
"Fns-sh")
12536 int button = Application->MessageBox(MessageStr.c_str(), L
"", MB_YESNO);
12548 else if(NewServiceActionEntryPtr->
Command ==
"Frh-sh")
12552 int button = Application->MessageBox(MessageStr.c_str(), L
"", MB_YESNO);
12564 else if(NewServiceActionEntryPtr->
Command ==
"F-nshs")
12568 int button = Application->MessageBox(MessageStr.c_str(), L
"", MB_YESNO);
12582 ShowMessage(
"Option unavailable");
12599 catch(
const Exception &e)
12611 bool Condition4Met =
false;
12613 NextServiceRef =
"";
12618 if(AVEPtr->Command ==
"Fns")
12620 Condition4Met =
true;
12621 NextServiceEntryPtr = AVEPtr->LinkedTrainEntryPtr;
12625 if(AVEPtr->Command ==
"Fns-sh")
12627 Condition4Met =
true;
12630 NextServiceEntryPtr = AVEPtr->NonRepeatingShuttleLinkEntryPtr;
12635 NextServiceEntryPtr = AVEPtr->LinkedTrainEntryPtr;
12640 if(AVEPtr->Command ==
"Frh-sh")
12648 Condition4Met =
true;
12649 NextServiceEntryPtr = AVEPtr->LinkedTrainEntryPtr;
12654 if(AVEPtr->Command ==
"F-nshs")
12656 Condition4Met =
true;
12657 NextServiceEntryPtr = AVEPtr->LinkedTrainEntryPtr;
12667 if(AVEPtr->LocationName == CurLoc)
12669 if((AVEPtr->FormatType ==
TimeTimeLoc) || ((AVEPtr->FormatType ==
TimeLoc) && (AVEPtr->ArrivalTime > TDateTime(0))) || (AVEPtr->Command ==
"pas") )
12693 int SkippedEvents = 0;
12696 if((AVEPtr->Command ==
"cdt") || (AVEPtr->Command ==
"pas") || (AVEPtr->SequenceType ==
Finish) ||
12697 ((AVEPtr->FormatType ==
TimeLoc) && (AVEPtr->DepartureTime != TDateTime(-1))))
12716 +
" timetabled events skipped before it became the new service";
12724 catch(
const Exception &e)
12739 bool LocFound =
false;
12741 int SkippedEvents = 0;
12743 for(AVEPtr = Train.
ActionVectorEntryPtr; AVEPtr <= &Train.TrainDataEntryPtr->ActionVector.back(); AVEPtr++)
12762 else if(AVEPtr->
Command ==
"pas")
12781 ShowMessage(
"New service location not found");
12788 +
" timetabled events skipped before the new service arrived at " + LocationName;
12796 catch(
const Exception &e)
12831 catch(
const Exception &e)
12847 if(NextElementPos < 0)
12849 throw Exception(
"Error, no element in front in PassRedSignalMenuItemClick");
12860 throw Exception(
"Error, next element not a signal type in PassRedSignalMenuItemClick");
12874 catch(
const Exception &e)
12900 int NextElementPos = -1;
12902 int NextEntryPos = -1;
12910 if((NextElementPos > -1) && (NextEntryPos > -1))
12920 catch(
const Exception &e)
12939 UnicodeString Message = UnicodeString(Train.
HeadCode) +
" will be removed from the railway - proceed?";
12940 int button = Application->MessageBox(Message.c_str(), L
"Please confirm", MB_YESNO);
12953 AnsiString LocName =
"";
12958 if((LocName ==
"") && (Train.
MidElement > -1))
12966 if((LocName ==
"") && (Train.
MidElement > -1))
13013 int FirstRouteElementVecPos = LeadTrackElement.
Conn[Train.
LeadExitPos];
13023 bool FirstPass =
true;
13030 if(FirstPass && (TVPos2 != FirstRouteElementVecPos))
13109 catch(
const Exception &e)
13124 Application->Terminate();
13138 catch(
const Exception &e)
13166 UnicodeString MessStr =
"";
13169 MessStr = UnicodeString(
"The railway and the timetable have both changed, exit without saving either?");
13173 MessStr = UnicodeString(
"The railway has changed, exit without saving?");
13177 MessStr = UnicodeString(
"The timetable has changed, exit without saving?");
13179 int button = Application->MessageBox(MessStr.c_str(), L
"Please confirm", MB_YESNO);
13191 UnicodeString MessageStr =
"Please note that the session will be lost if it hasn't been saved. Do you still wish to exit?";
13194 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
13213 catch(
const Exception &e)
13227 if((Shift.Contains(ssAlt)) && (Shift.Contains(ssCtrl)))
13240 else if(Key ==
'3')
13252 else if(Key ==
'4')
13256 else if(Key ==
'5')
13258 TMsgDlgButtons Buttons;
13259 Buttons << mbYes << mbNo;
13260 if(MessageDlg(
"Do you wish to allow facing signals next to bridges? If so please be aware that routes cannot be truncated to these signals.",
13261 mtWarning, Buttons, 0) == mrYes)
13271 else if(Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
13275 else if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl) && !Shift.Contains(ssAlt))
13287 if((Key != VK_SHIFT) && (Key != VK_CONTROL))
13305 else if(Key == VK_DOWN)
13312 else if(Key == VK_LEFT)
13319 else if(Key == VK_RIGHT)
13326 else if(Key == VK_HOME)
13334 else if(Key == VK_END)
13341 else if(Key == VK_END)
13356 if(Shift.Contains(ssShift) && !Shift.Contains(ssAlt) && !Shift.Contains(ssCtrl) &&
NewHomeButton->Enabled &&
NewHomeButton->Visible)
13368 if(!Shift.Contains(ssCtrl))
13432 if(Key ==
'S' || Key ==
's')
13443 if(Shift.Contains(ssShift))
13458 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl) && !Shift.Contains(ssAlt))
13505 if(Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
13511 if(Key ==
'S' || Key ==
's')
13517 if(!Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
13528 if(!Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
13535 if(!Shift.Contains(ssShift) && Shift.Contains(ssCtrl))
13541 if(Key ==
'S' || Key ==
's')
13547 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
13568 if(!Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
13575 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
13581 if(Key ==
'S' || Key ==
's')
13586 else if(Key ==
'H' || Key ==
'h')
13599 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
13670 if(
SaveTTButton->Enabled && (Key ==
'T' || Key ==
't'))
13693 if(
FloatingInfoMenu->Enabled && !Shift.Contains(ssAlt) && Shift.Contains(ssCtrl) && Shift.Contains(ssShift))
13695 if(Key ==
'I' || Key ==
'i')
13701 if(Key ==
'S' || Key ==
's')
13705 else if(Key ==
'T' || Key ==
't')
13714 catch(
const Exception &e)
13724 if((Key != VK_SHIFT) && (Key != VK_CONTROL))
13846 catch(
const Exception &e)
13859 Application->HelpKeyword(u
"Introduction");
13861 catch(
const Exception &e)
13871 const UnicodeString Link =
"http://www.railwayoperationsimulator.com";
13872 ::ShellExecute(Handle, NULL, (Link).c_str(), NULL, NULL, SW_SHOWNORMAL);
13895 catch(
const Exception &e)
13921 catch(
const Exception &e)
13947 catch(
const Exception &e)
14003 bool ErrorFlag =
false, TooBigFlag =
false;
14024 if(!ErrorFlag && !TooBigFlag)
14034 int KPH = (MPH * 1.609344) + 0.5;
14041 int MPH = (KPH * 0.621371) + 0.5;
14052 catch(
const EConvertError &ec)
14057 catch(
const Exception &e)
14092 bool ErrorFlag =
false, TooBigFlag =
false;
14113 if(!ErrorFlag && !TooBigFlag)
14123 int KW = (HP * 0.745699872) + 0.5;
14130 int HP = (KW * 1.340482574) + 0.5;
14141 catch(
const EConvertError &ec)
14146 catch(
const Exception &e)
14159 bool ErrorFlag =
false, TooBigFlag =
false;
14180 if(!ErrorFlag && !TooBigFlag)
14190 int KPH = (MPH * 1.609344) + 0.5;
14197 int MPH = (KPH * 0.621371) + 0.5;
14208 catch(
const EConvertError &ec)
14213 catch(
const Exception &e)
14227 bool ErrorFlag =
false, TooLongFlag =
false;
14230 for(
int x = 1; x <=
MileEdit->Text.Length(); x++)
14242 for(
int x = 1; x <=
ChainEdit->Text.Length(); x++)
14254 for(
int x = 1; x <=
YardEdit->Text.Length(); x++)
14266 TooLongFlag =
true;
14269 if(!ErrorFlag && !TooLongFlag)
14271 int Miles = 0, Chains = 0, Yards = 0, Metres = 0;
14284 Metres = int((Miles * 1609.344) + (Chains * 20.1168) + (Yards * 0.9144) + 0.5);
14293 catch(
const EConvertError &ec)
14298 catch(
const Exception &e)
14329 catch(
const Exception &e)
14366 "Changes have been made to the timetable clock - you may wish to save a session before resuming operation.\n\nTo cancel all changes re-click the 'Adjust the timetable clock' button then click the reset button BEFORE resuming operation.";
14375 catch(
const Exception &e)
14393 catch(
const Exception &e)
14412 catch(
const Exception &e)
14431 catch(
const Exception &e)
14450 catch(
const Exception &e)
14469 catch(
const Exception &e)
14488 catch(
const Exception &e)
14507 catch(
const Exception &e)
14527 catch(
const Exception &e)
14546 catch(
const Exception &e)
14560 double TTClockIncrement = 1.0 / 24;
14566 catch(
const Exception &e)
14580 double TTClockIncrement = 1.0 / 144;
14586 catch(
const Exception &e)
14600 double TTClockIncrement = 1.0 / 1440;
14606 catch(
const Exception &e)
14663 catch(
const Exception &e)
14677 InfoPanel->Caption =
"PRE-START: Presetting automatic signal routes";
14688 Screen->Cursor = TCursor(-11);
14690 bool PointsChanged, AtLeastOneSet =
false;
14691 int LastIteratorValue = 0;
14700 AtLeastOneSet =
true;
14717 ShowMessage(
"No presettable automatic signal routes are available");
14719 Screen->Cursor = TCursor(-2);
14722 catch(
const Exception &e)
14737 int DispW = (
Interface->Width - 64 - 16) / 16;
14739 int DispH = (
Interface->Height - 192) / 16;
14771 catch(
const Exception &e)
14801 catch(
const Exception &e)
14827 SigImagePanel->Caption =
"Signals will be on the right hand side of the track";
14844 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
14852 catch(
const Exception &e)
14871 bool TooBigFlag =
false, BadCharsFlag =
false;
14876 for(
int x = 1; x <=
MTBFEditBox->Text.Length(); x++)
14880 BadCharsFlag =
true;
14893 ShowMessage(
"Maximum value allowed is 9999");
14902 ShowMessage(
"Value must be a whole number with no special characters");
14919 catch(
const Exception &e)
14937 "Values can only be entered or changed in Pre-Start mode\ni.e. after selecting 'Operate railway' but before clicking 'Run'");
14941 catch(
const Exception &e)
14974 catch(
const Exception &e)
15000 catch(
const Exception &e)
15016 catch(
const Exception &e)
15037 catch(
const Exception &e)
15061 catch(
const Exception &e)
15078 catch(
const Exception &e)
15095 catch(
const Exception &e)
15111 ShowMessage(
"No boxes ticked!");
15115 Screen->Cursor = TCursor(-11);
15116 AnsiString TTTitle;
15130 ShowMessage(
"Analysis complete and file created");
15135 Screen->Cursor = TCursor(-2);
15138 catch(
const Exception &e)
15155 catch(
const Exception &e)
15169 int LengthInt, SpeedInt;
15170 std::ifstream ConfigFile((
CurDir +
"\\Config.txt").c_str());
15171 if(ConfigFile.fail())
15176 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
15182 "This program is free software released under the terms of the GNU General Public License Version 3, as published by the Free Software Foundation. "
15183 " It may be used or redistributed in accordance with that license and is released in the hope that it will be useful, but WITHOUT ANY WARRANTY; "
15184 "without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details - "
15185 "you should have received a copy along with this program but if not see <http://www.gnu.org/licenses/>.");
15190 AnsiString ConfigStr =
"";
15191 bool ContinueFlag =
false;
15196 if(ConfigFile.eof())
15202 if(ConfigStr ==
"")
15206 if(ConfigStr[1] ==
'#')
15210 for(
int x = 1; x <= ConfigStr.Length(); x++)
15212 if(ConfigStr[x] ==
'#')
15214 ConfigStr = ConfigStr.SubString(1, x - 1);
15216 while((ConfigStr.SubString(ConfigStr.Length(), 1) == AnsiString(
' ')) || (ConfigStr.SubString(ConfigStr.Length(), 1) == AnsiString(
'\t')))
15218 ConfigStr = ConfigStr.SubString(1, ConfigStr.Length() - 1);
15223 AnsiString ConfigValue = ConfigStr.SubString(9, ConfigStr.Length() - 8);
15224 if((ConfigStr.SubString(1, 8) ==
"Signals=") && FirstLoad)
15227 while((ConfigValue.SubString(1, 1) == AnsiString(
' ')) || (ConfigValue.SubString(1, 1) == AnsiString(
'\t')))
15229 ConfigValue = ConfigValue.SubString(2, ConfigValue.Length() - 1);
15243 SigImagePanel->Caption =
"Signals will be on the right hand side of the track";
15261 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
15268 if((ConfigStr.SubString(1, 8) ==
"BgndCol=") && FirstLoad)
15272 if(ConfigValue ==
"white")
15276 else if(ConfigValue ==
"blue")
15281 if((ConfigStr.SubString(1, 8) ==
"RLYLocn=") && FirstLoad)
15283 if(DirectoryExists(ConfigValue))
15285 SaveRailwayDialog->InitialDir = ConfigStr.SubString(9, ConfigStr.Length() - 8);
15286 LoadRailwayDialog->InitialDir = ConfigStr.SubString(9, ConfigStr.Length() - 8);
15289 else if((ConfigStr.SubString(1, 8) ==
"TTBLocn=") && FirstLoad)
15291 if(DirectoryExists(ConfigValue))
15293 TimetableDialog->InitialDir = ConfigStr.SubString(9, ConfigStr.Length() - 8);
15294 SaveTTDialog->InitialDir = ConfigStr.SubString(9, ConfigStr.Length() - 8);
15297 else if((ConfigStr.SubString(1, 8) ==
"SSNLocn=") && FirstLoad)
15299 if(DirectoryExists(ConfigValue))
15301 LoadSessionDialog->InitialDir = ConfigStr.SubString(9, ConfigStr.Length() - 8);
15304 else if(ConfigStr.SubString(1, 8) ==
"Length =")
15306 for(
int x = 1; x <= ConfigValue.Length(); x++)
15308 if((ConfigValue[x] <
'0') || (ConfigValue[x] >
'9'))
15310 ContinueFlag =
true;
15316 ContinueFlag =
false;
15319 LengthInt = ConfigStr.SubString(9, ConfigStr.Length() - 8).ToInt();
15324 if(LengthInt > 99999)
15333 else if(ConfigStr.SubString(1, 8) ==
"Speed =")
15335 for(
int x = 1; x <= ConfigValue.Length(); x++)
15337 if((ConfigValue[x] <
'0') || (ConfigValue[x] >
'9'))
15339 ContinueFlag =
true;
15345 ContinueFlag =
false;
15348 SpeedInt = ConfigStr.SubString(9, ConfigStr.Length() - 8).ToInt();
15353 else if(SpeedInt > 400)
15368 while(!ConfigFile.eof());
15369 ConfigFile.close();
15373 catch(
const Exception &e)
15375 ShowMessage(
"Unable to load the configuration file, it appears to be corrupt. It will be re-written correctly when the program closes.\n\n"
15376 "Default values will be used for the current session.");
15379 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
15404 AnsiString ColourStr =
"", SignalStr =
"", LengthStr =
"", SpeedStr =
"";
15405 remove((
CurDir +
"\\Config.txt").c_str());
15406 std::ofstream ConfigFile((
CurDir +
"\\Config.txt").c_str());
15407 ColourStr =
"black";
15408 SignalStr =
"left";
15421 ColourStr =
"white";
15425 ColourStr =
"blue";
15429 SignalStr =
"right";
15431 ConfigFile << AnsiString(
"#This file contains a list of parameters that are saved after each use of the program and reloaded for the "
15432 "next use. Track element length and speed limit values after the = sign may be changed and the configuration file reloaded "
15433 "during play, but please do not change anything else. Comments begin with '#' and are ignored by the program.\n\n");
15434 ConfigFile << AnsiString(
"Signals=") << SignalStr <<
'\n';
15435 ConfigFile << AnsiString(
"BgndCol=") << ColourStr <<
'\n';
15436 ConfigFile << AnsiString(
"RLYLocn=") << AnsiString(
LoadRailwayDialog->InitialDir) <<
'\n';
15437 ConfigFile << AnsiString(
"TTBLocn=") << AnsiString(
TimetableDialog->InitialDir) <<
'\n';
15438 ConfigFile << AnsiString(
"SSNLocn=") << AnsiString(
LoadSessionDialog->InitialDir) <<
'\n';
15439 ConfigFile << AnsiString(
"Length =") << LengthStr <<
" #default track element length in metres (not less than 10)\n";
15440 ConfigFile << AnsiString(
"Speed =") << SpeedStr <<
" #default track element speed limit in km/h (not less than 10 and not greater than 400)\n";
15441 ConfigFile.close();
15444 catch(
const Exception &e)
15446 ShowMessage(
"Unable to save configuration file, file won't be updated");
15489 int WidthNum = int(
MainScreen->Width / 160) + 1;
15490 int HeightNum = int(
MainScreen->Height / 144) + 1;
15491 for(
int x = 0; x < WidthNum; x++)
15493 for(
int y = 0; y < HeightNum; y++)
15598 bool BreakFlag =
false;
15707 ZoomButton->Glyph->LoadFromResourceName(0,
"ZoomOut");
15741 InfoPanel->Caption =
"CONNECTING GAPS: Click on connecting element";
15757 UnicodeString MessageStr =
"The railway has changed, close it without saving?";
15758 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
15810 std::ifstream VecFile(FileName);
15812 if(VecFile.is_open())
15832 bool GraphicsFollow =
false;
15833 int NumberOfActiveElements;
15846 if(!(EveryPrefDir->CheckOnePrefDir(0, NumberOfActiveElements, VecFile)))
15877 TDateTime First, Second;
15878 bool Finished =
false;
15880 First = TDateTime::CurrentDateTime();
15881 double TimeVal1 = 86400000 * double(First);
15885 Second = TDateTime::CurrentDateTime();
15886 double TimeVal2 = 86400000 * double(Second);
15887 if((TimeVal2 - TimeVal1) > Msec)
15947 if((LinkNumber1 == 1) || (LinkNumber1 == 3) || (LinkNumber1 == 7) || (LinkNumber1 == 9))
15955 if((LinkNumber2 == 1) || (LinkNumber2 == 3) || (LinkNumber2 == 7) || (LinkNumber2 == 9))
16118 InfoPanel->Caption =
"Select an option from the File, Mode or Help menus";
16278 Screen->Cursor = TCursor(-11);
16286 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Select preferred direction start location (right click to erase)";
16293 ShowMessage(
"Preferred direction correctness can be difficult to check by eye\n"
16294 "alone, especially for large railways, so an automated conflict\n"
16295 "check is available in the 'Edit' menu when in preferred\n"
16296 "direction mode.\n\n"
16297 "This message will not be shown again.");
16320 Screen->Cursor = TCursor(-2);
16369 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
16382 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
16409 ShowMessage(
"Performance logfile failed to open, logs won't be saved. Ensure that there is a folder named " +
PERFLOG_DIR_NAME +
16410 " in the folder where the 'Railway.exe' program file resides");
16477 OAListBox->Items->Add(L
"locate train");
16481 OAListBox->Items->Add(L
"headcode for");
16485 OAListBox->Items->Add(L
"Left click and");
16486 OAListBox->Items->Add(L
"hold grey area");
16487 OAListBox->Items->Add(L
"to move panel");
16524 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
16549 OAListBox->Items->Add(L
"locate train");
16553 OAListBox->Items->Add(L
"headcode for");
16557 OAListBox->Items->Add(L
"Left click and");
16558 OAListBox->Items->Add(L
"hold grey area");
16559 OAListBox->Items->Add(L
"to move panel");
16573 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
16582 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
16639 InfoPanel->Caption =
"ADDING TRACK: Select element then left click to add it. Right click an element to remove it.";
16678 InfoPanel->Caption =
"ADDING GRAPHIC: Left click layout to add SELECTED graphic, right click to remove ANY graphic.";
16683 InfoPanel->Caption =
"SELECTING USER GRAPHIC: Select the graphic file then add as many as necessary to the layout.";
16687 int HLoc, VLoc, Count;
16689 if(div(Count, 2).rem == 1)
16691 ShowMessage(
"Can't connect, there are an odd number of gaps");
16706 ShowMessage(
"Error - Even number of gaps but all set after first call to HighLightOneGap");
16716 InfoPanel->Caption =
"CONNECTING GAPS: Click on connecting gap";
16723 InfoPanel->Caption =
"ADDING/EDITING TEXT: Left click to add, right click first letter to erase, or left click first letter to edit)";
16738 InfoPanel->Caption =
"MOVING TEXT OR GRAPHIC: If text left click first letter, if graphic left click anywhere, then drag";
16745 InfoPanel->Caption =
"NAMING LOCATIONS: Click on location element to add or change name";
16753 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Select first location (only non-default elements marked)";
16765 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Select next location";
16769 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
16784 InfoPanel->Caption =
"SELECTING: Select area - click left mouse && drag";
16794 InfoPanel->Caption =
"COPYING: Left click in selection && drag";
16820 bool EraseSuccessfulFlag, NeedToLink =
false, TextChangesMade =
false, GraphicChangesMade =
false;
16821 int ErasedTrackVectorPosition;
16822 Screen->Cursor = TCursor(-11);
16824 InfoPanel->Caption =
"CUT PROCESSING: Please do not click the mouse";
16831 if(EraseSuccessfulFlag)
16833 if(ErasedTrackVectorPosition > -1)
16846 int HighSelectVPos =
SelectRect.bottom * 16;
16852 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
16860 TextChangesMade =
true;
16870 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
16871 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
16874 GraphicChangesMade =
true;
16881 Screen->Cursor = TCursor(-2);
16888 InfoPanel->Caption =
"CUTTING: Left click in selection && drag";
16905 if(NeedToLink || TextChangesMade || GraphicChangesMade)
16933 UnicodeString MessageStr =
16934 "Please be aware of the relevant conditions when pasting " "a railway segment from a different application.\n"
16935 "These are set out in section 3.5 of the manual and " "on-screen help under the heading 'Pasting in an application "
16936 "after cutting or copying from a different application'.\n\n" "This warning will not be shown again.\n\n" "Proceed?";
16937 int button = Application->MessageBox(MessageStr.c_str(), L
"Warning", MB_YESNO | MB_ICONWARNING);
16949 Application->MessageBoxW(L
"Unable to paste (clipboard is invalid) - possibly because another application has changed it)", L
"Warning", MB_OK | MB_ICONWARNING);
16951 TrainController->
LogEvent(
"ValidResult false in case Pasting - probably due to error in RecoverClipboard - see earlier log");
16963 Clipboard()->Clear();
16964 Clipboard()->Close();
16967 bool NeedToLink =
false;
16968 bool TrackLinkingRequiredFlag;
16969 Screen->Cursor = TCursor(-11);
16971 InfoPanel->Caption =
"PASTING: Please wait";
16978 bool TrackEraseSuccessfulFlag;
16979 int ErasedTrackVectorPosition;
16981 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
16983 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
16986 if(ErasedTrackVectorPosition > -1)
17003 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
17020 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
17021 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
17035 AnsiString LocName;
17054 int HPos = 0, VPos = 0;
17067 bool InternalChecks =
false;
17071 TrackLinkingRequiredFlag, InternalChecks);
17087 if(TrackLinkingRequiredFlag)
17102 PDVIt->HLoc += HDiff;
17103 PDVIt->VLoc += VDiff;
17108 throw Exception(
"Failed to find TrackVectorPosition in PrefDir setting for Paste");
17110 PDVIt->SetTrackVectorPosition(ATVecPos);
17113 for(
int x = 0; x < 4; x++)
17115 PDVIt->Conn[x] = -1;
17116 PDVIt->ConnLinkPos[x] = -1;
17128 TextPtr->HPos += HDiff * 16;
17129 TextPtr->VPos += VDiff * 16;
17130 AnsiString TempString = TextPtr->TextString;
17146 if(TextPtr->TextString.SubString(1, 4) ==
"##**")
17148 TempString = TextPtr->TextString.SubString(5, TextPtr->TextString.Length());
17151 TextPtr->TextString =
"";
17164 for(TTrack::TUserGraphicVector::iterator GraphicPtr =
Track->
SelectGraphicVector.begin(); GraphicPtr < Track->SelectGraphicVector.end();
17167 GraphicPtr->HPos += HDiff * 16;
17168 GraphicPtr->VPos += VDiff * 16;
17183 Screen->Cursor = TCursor(-2);
17203 UnicodeString MessageStr =
"Selected area will be deleted - proceed?";
17204 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
17209 bool EraseSuccessfulFlag, NeedToLink =
false, TextChangesMade =
false, GraphicChangesMade =
false;
17210 int ErasedTrackVectorPosition;
17211 Screen->Cursor = TCursor(-11);
17213 InfoPanel->Caption =
"DELETING: Please wait";
17220 if(EraseSuccessfulFlag)
17222 if(ErasedTrackVectorPosition > -1)
17234 int HighSelectVPos =
SelectRect.bottom * 16;
17240 AnsiString Check = TextPtr->TextString;
17241 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
17249 TextChangesMade =
true;
17268 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
17269 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
17274 if((UserGraphicPtr->HPos == GraphicPtr->HPos) && (UserGraphicPtr->VPos == GraphicPtr->VPos) &&
17275 (UserGraphicPtr->Width == GraphicPtr->Width) && (UserGraphicPtr->Height == GraphicPtr->Height) &&
17276 (UserGraphicPtr->FileName == GraphicPtr->FileName))
17279 GraphicChangesMade =
true;
17299 if(NeedToLink || TextChangesMade || GraphicChangesMade)
17303 Screen->Cursor = TCursor(-2);
17323 catch (
const EClipboardException &e)
17361 bool LeadingPointsAtLastElement =
false;
17364 if(LeadingPointsAtLastElement)
17366 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Can't end on leading points, select next location or truncate";
17371 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Select next preferred direction location (right click to truncate)";
17376 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Add selection or select next location (right click to truncate)";
17391 InfoPanel->Caption =
"SELECTING: Select area - click left mouse && drag";
17434 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
17508 Display->
PerformanceLog(15, TimeMessage +
"Timetable clock speed changed to one sixteenth normal");
17516 if(TTClockTimeChange > 0.000347)
17519 int MinsIncrease = ((TTClockTimeChange * 1440) + 0.5);
17520 int HoursIncrease = 0;
17521 while(MinsIncrease >= 60)
17524 MinsIncrease -= 60;
17526 if(HoursIncrease == 0)
17528 TimeMessage +=
"Timetable clock incremented by " + AnsiString(MinsIncrease) +
"m";
17530 else if(MinsIncrease == 0)
17532 TimeMessage +=
"Timetable clock incremented by " + AnsiString(HoursIncrease) +
"h";
17536 TimeMessage +=
"Timetable clock incremented by " + AnsiString(HoursIncrease) +
"h " + AnsiString(MinsIncrease) +
"m";
17548 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
17556 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
17565 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
17595 float LockDelay = 120.0;
17601 bool BreakFlag =
false;
17605 if((TTClockTime - LRVIT->LockStartTime) > TDateTime(LockDelay / 86400))
17608 AnsiString(LRVIT->LastTrackVectorPosition));
17609 while(Route.
LastElementPtr(9)->GetTrackVectorPosition() != LRVIT->TruncateTrackVectorPosition)
17626 if(Route.
LastElementPtr(17)->GetTrackVectorPosition() == LRVIT->TruncateTrackVectorPosition)
17667 int TempLockedVectorNumber;
17677 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->FirstDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 0))
17680 AutoSigVectorIT->AccessNumber++;
17683 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->SecondDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 1))
17686 AutoSigVectorIT->AccessNumber++;
17689 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->ThirdDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 2))
17692 AutoSigVectorIT->AccessNumber++;
17700 if(AutoSigVectorIT->AccessNumber > 2)
17714 TPoint MousePoint = Mouse->CursorPos;
17715 int ScreenX = MousePoint.x -
MainScreen->ClientOrigin.x;
17716 int ScreenY = MousePoint.y -
MainScreen->ClientOrigin.y;
17729 ((MousePoint.y - ClientOrigin.y) >=
PerformancePanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
17741 ((MousePoint.y - ClientOrigin.y) >=
TimetableEditPanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
17750 AnsiString TrackFloat =
"", TrainStatusFloat =
"", TrainTTFloat =
"";
17751 bool ShowTrackFloatFlag =
false, ShowTrainStatusFloatFlag =
false, ShowTrainTTFloatFlag =
false;
17761 bool MouseOverOAPanel =
false;
17766 ((MousePoint.y - ClientOrigin.y) >=
OperatorActionPanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
17769 MouseOverOAPanel =
true;
17775 bool ActiveTrackFoundFlag =
false, InactiveTrackFoundFlag =
false, TwoTrack =
false;
17776 AnsiString Length01Str =
"", Length23Str =
"", SpeedLimit01Str =
"", SpeedLimit23Str =
"";
17777 AnsiString StationEntryStopLinkPos1Str =
"", StationEntryStopLinkPos2Str =
"";
17778 AnsiString ATrackSN =
"", ATrackTN =
"", IATrackSN =
"", LengthAndSpeedCaption =
"";
17779 AnsiString SigAspectString =
"";
17783 if(InactiveTrackFoundFlag)
17788 if(ActiveTrackFoundFlag)
17795 if((ATrackTN !=
"") && (!InactiveTrackFoundFlag || ((InactiveTrackElement.
TrackType !=
Platform) &&
17799 ShowMessage(
"Error - Track has timetable name without corresponding plat/named loc");
17804 ShowMessage(
"Error - plat/named loc and track have different names, or plat/named loc named but not track");
17810 Length01Str = AnsiString(ActiveTrackElement.
Length01);
17811 if(Length01Str ==
"-1")
17813 Length01Str =
"Not Set";
17815 SpeedLimit01Str = AnsiString(ActiveTrackElement.
SpeedLimit01);
17816 if(SpeedLimit01Str ==
"-1")
17818 SpeedLimit01Str =
"Not Set";
17822 Length23Str = AnsiString(ActiveTrackElement.
Length23);
17823 if(Length23Str ==
"-1")
17825 Length23Str =
"Not Set";
17827 SpeedLimit23Str = AnsiString(ActiveTrackElement.
SpeedLimit23);
17828 if(SpeedLimit23Str ==
"-1")
17830 SpeedLimit23Str =
"Not Set";
17834 LengthAndSpeedCaption =
"Straight track length = " + Length01Str +
" m" +
'\n' +
"Diverging track length = " + Length23Str +
" m" +
'\n' +
17835 "Straight track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Diverging track speed limit = " + SpeedLimit23Str +
" km/h";
17839 LengthAndSpeedCaption =
"Left diverging track length = " + Length01Str +
" m" +
'\n' +
"Right diverging track length = " + Length23Str +
17840 " m" +
'\n' +
"Left diverging track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Right diverging track Speed Limit = " +
17841 SpeedLimit23Str +
" km/h";
17846 if((ActiveTrackElement.
SpeedTag == 15) || (ActiveTrackElement.
SpeedTag == 46))
17848 LengthAndSpeedCaption =
"Horizontal track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
" m" +
'\n' +
17849 "Horizontal track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit23Str +
" km/h";
17851 else if(ActiveTrackElement.
SpeedTag == 47)
17853 LengthAndSpeedCaption =
"Horizontal track length = " + Length23Str +
" m" +
'\n' +
"Other track length = " + Length01Str +
" m" +
'\n' +
17854 "Horizontal track speed limit = " + SpeedLimit23Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit01Str +
" km/h";
17856 else if(ActiveTrackElement.
SpeedTag == 45)
17858 LengthAndSpeedCaption =
"Vertical track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
" m" +
'\n' +
17859 "Vertical track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit23Str +
" km/h";
17861 else if(ActiveTrackElement.
SpeedTag == 44)
17863 LengthAndSpeedCaption =
"Vertical track length = " + Length23Str +
" m" +
'\n' +
"Other track length = " + Length01Str +
" m" +
'\n' +
17864 "Vertical track speed limit = " + SpeedLimit23Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit01Str +
" km/h";
17866 else if(ActiveTrackElement.
SpeedTag == 16)
17868 LengthAndSpeedCaption =
"Top left to bottom right track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
17869 " m" +
'\n' +
"Top left to bottom right track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " +
17870 SpeedLimit23Str +
" km/h";
17875 LengthAndSpeedCaption =
"Top track length = " + Length01Str +
" m" +
'\n' +
"Bottom track length = " + Length23Str +
" m" +
'\n' +
17876 "Top track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Bottom track speed limit = " + SpeedLimit23Str +
" km/h";
17881 LengthAndSpeedCaption =
"Track length = " + Length01Str +
" m" +
'\n' +
"Track speed limit = " + SpeedLimit01Str +
" km/h";
17884 if(ActiveTrackFoundFlag)
17888 ShowTrackFloatFlag =
true;
17891 TrackFloat =
"Location = " + ATrackTN +
'\n' + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
17893 else if(ATrackSN !=
"")
17895 TrackFloat =
"Location = " + ATrackSN +
'\n' + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
17898 else if(InactiveTrackFoundFlag)
17900 TrackFloat =
"Location unnamed\n" + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
17905 TrackFloat = LengthAndSpeedCaption +
'\n' +
"Track Element ID = " + AnsiString(ActiveTrackElement.
ElementID);
17911 SigAspectString =
"\nThree-aspect signal";
17915 SigAspectString =
"\nTwo-aspect signal";
17919 SigAspectString =
"\nGround signal";
17923 SigAspectString =
"\nFour-aspect signal";
17925 TrackFloat += SigAspectString;
17928 else if(InactiveTrackFoundFlag)
17931 ShowTrackFloatFlag =
true;
17934 if(IATrackSN ==
"")
17936 TrackFloat =
"Location unnamed\nID = " + AnsiString(InactiveTrackElement.
ElementID);
17940 TrackFloat =
"Location = " + IATrackSN +
'\n' +
"ID = " + AnsiString(InactiveTrackElement.
ElementID);
17945 TrackFloat =
"ID = " + AnsiString(InactiveTrackElement.
ElementID);
17951 bool OAListBoxFloatRequired =
false;
17956 AnsiString FormatOneDPStr =
"####0.0";
17957 AnsiString FormatNoDPStr =
"#######0";
17958 AnsiString MaxBrakeStr =
"";
17959 AnsiString SpecialStr =
"";
17964 int X =
OAListBox->ScreenToClient(MousePoint).x;
17965 int Y =
OAListBox->ScreenToClient(MousePoint).y;
17966 int TrainID = -1, ContinuationPos = -1;
17969 OAListBoxFloatRequired =
true;
17972 ShowTrainStatusFloatFlag =
true;
17976 ShowTrainTTFloatFlag =
true;
17978 if((TrainID > -1) && (ShowTrainStatusFloatFlag || ShowTrainTTFloatFlag))
17984 else if(ContinuationPos > -1)
17991 if(!OAListBoxFloatRequired)
17994 if(FoundFlag && !MouseOverOAPanel)
18002 ShowTrainStatusFloatFlag =
true;
18007 ShowTrainTTFloatFlag =
true;
18017 TrainStatusFloat =
"No trains expected";
18018 TrainTTFloat =
"No timetable";
18021 ShowTrainStatusFloatFlag =
true;
18025 ShowTrainTTFloatFlag =
true;
18036 AnsiString Caption;
18038 if(!ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
18044 else if(ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
18046 Caption = TrackFloat;
18048 else if(!ShowTrackFloatFlag && ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
18050 Caption = TrainStatusFloat;
18052 else if(ShowTrackFloatFlag && ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
18054 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
18056 else if(!ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
18058 if(TrainStatusFloat ==
"No trains expected")
18060 Caption = TrainStatusFloat;
18064 Caption = TrainTTFloat;
18067 else if(ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
18069 if(TrainStatusFloat ==
"No trains expected")
18071 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
18075 Caption = TrainTTFloat +
'\n' +
'\n' + TrackFloat;
18078 else if(!ShowTrackFloatFlag && ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
18080 if(TrainStatusFloat ==
"No trains expected")
18082 Caption = TrainStatusFloat;
18086 Caption = TrainStatusFloat +
'\n' +
'\n' + TrainTTFloat;
18089 else if(ShowTrackFloatFlag && ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
18091 if(TrainStatusFloat ==
"No trains expected")
18093 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
18097 Caption = TrainStatusFloat +
'\n' +
'\n' + TrainTTFloat +
'\n' +
'\n' + TrackFloat;
18100 int WindowOffsetLeft = 16;
18101 int WindowOffsetRight = 16;
18102 if(OAListBoxFloatRequired)
18104 WindowOffsetLeft = 32;
18105 WindowOffsetRight = 64;
18110 int Left = ScreenX +
MainScreen->Left + WindowOffsetRight;
18115 Left = ScreenX -
FloatingPanel->Width + 32 - WindowOffsetLeft;
18153 AnsiString &TrainTTFloat)
18162 (CTEIt->second.TrainDataEntryPtr->TrainOperatingDataVector.at(CTEIt->second.RepeatNumber).RunningEntry !=
NotStarted)))
18169 AnsiString ServiceReferenceInfo =
"";
18173 if(CTEIt->second.RepeatNumber == 0)
18177 ServiceReferenceInfo =
"\nFirst service of ref. " + TTDEPtr->
ServiceReference;
18181 ServiceReferenceInfo =
"\nFirst service";
18186 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(CTEIt->second.RepeatNumber);
18190 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(CTEIt->second.RepeatNumber) +
" of ref. " + TTDEPtr->
ServiceReference;
18197 ServiceReferenceInfo =
"\nService reference " + TTDEPtr->
ServiceReference;
18202 SpecialStr =
"\nTrain under signaller control";
18204 if(EntrySpeed > LineSpeedLimit)
18206 EntrySpeed = LineSpeedLimit;
18212 if(EntrySpeed > LineSpeedLimit)
18214 EntrySpeed = LineSpeedLimit;
18219 TDateTime TempTime = CTEIt->first;
18221 TrainStatusFloat = CTEIt->second.HeadCode +
": " + CTEIt->second.Description + ServiceReferenceInfo +
"\nEntry speed " +
18222 AnsiString::FormatFloat(FormatNoDPStr, EntrySpeed) +
"km/h" + SpecialStr +
"\nDelayed, was due at " +
Utilities->
Format96HHMM(TempTime);
18226 TDateTime TempTime = CTEIt->first;
18228 TrainStatusFloat = CTEIt->second.HeadCode +
": " + CTEIt->second.Description + ServiceReferenceInfo +
"\nEntry speed " +
18229 AnsiString::FormatFloat(FormatNoDPStr, EntrySpeed) +
"km/h" + SpecialStr +
"\nExpected at " +
Utilities->
Format96HHMM(TempTime);
18236 CTEIt->second.IncrementalDigits);
18250 AnsiString HeadCode =
"", ServiceReferenceInfo =
"", Status =
"", CurrSpeedStr =
"", BrakePCStr =
"", NextStopStr =
"", TimeLeftStr =
"",
18251 TimeToNextMovementStr =
"", MassStr =
"", PowerStr =
"";
18252 AnsiString FormatOneDPStr =
"####0.0", MaxBrakeStr =
"", MaxSpeedStr =
"", TrainStatusFloat;
18256 MassStr = AnsiString::FormatFloat(FormatNoDPStr, ((
double)Train.
Mass) / 1000);
18257 PowerStr = AnsiString::FormatFloat(FormatNoDPStr, Train.
PowerAtRail / 1000 / 0.8);
18260 MaxSpeedStr =
"30";
18264 MaxSpeedStr = AnsiString::FormatFloat(FormatNoDPStr, Train.
MaxRunningSpeed);
18269 TDateTime TimeLeft;
18271 MaxBrakeStr = AnsiString::FormatFloat(FormatNoDPStr, (Train.
MaxBrakeRate * Train.
Mass / 9810));
18283 ServiceReferenceInfo =
"\nFirst service";
18288 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(Train.
RepeatNumber);
18306 Status =
"Stopped on signaller's instruction";
18310 Status =
"Not in service";
18314 Status =
"Stopped at buffers";
18318 Status =
"Stopped at signal";
18322 Status =
"Stopped - forward track occupied";
18336 Status =
"Stopped without power - train failed";
18340 Status =
"Stopped without power";
18345 Status =
"Stopped - signal passed at danger";
18349 Status =
"Derailed";
18353 Status =
"Crashed";
18361 Status =
"Accelerating";
18368 if(BrakePCRate < 55)
18370 Status =
"Light braking";
18372 else if(BrakePCRate < 90)
18374 Status =
"Heavy braking";
18378 Status =
"Emergency braking";
18385 if(BrakePCRate < 55)
18387 Status =
"Light braking";
18389 else if(BrakePCRate < 90)
18391 Status =
"Heavy braking";
18395 Status =
"Emergency braking";
18402 Status =
"Accelerating";
18408 Status =
"Accelerating";
18410 ((Train.
ExitSpeedFull - Train.
ExitSpeedHalf) * (
double(ElapsedDeltaT - FirstHalfTimeDeltaT) / double(SecondHalfTimeDeltaT)));
18419 Status =
"Coasting - train failed";
18423 Status =
"Coasting - no power";
18429 Status =
"Constant speed";
18440 Status =
"Coasting - train failed";
18444 Status =
"Coasting - no power";
18450 Status =
"Constant speed";
18458 NextStopStr =
"At signaller's discretion";
18462 NextStopStr =
"None";
18471 SpecialStr =
"Train under signaller control" + AnsiString(
'\n');
18475 SpecialStr =
"Restricted speed - being called on" + AnsiString(
'\n');
18478 if(RemTimeHalf < 0)
18483 if(RemTimeFull < 0)
18487 if(RemTimeHalf > 0)
18489 TimeLeft = RemTimeHalf;
18493 TimeLeft = RemTimeFull;
18495 TimeToNextMovementStr =
"Time to next movement (sec) = " + TimeLeftStr.FormatFloat(FormatOneDPStr, TimeLeft);
18498 TimeToNextMovementStr =
"";
18504 TrainStatusFloat = HeadCode +
": " + Train.
TrainDataEntryPtr->
Description + ServiceReferenceInfo +
'\n' +
"Maximum train speed " + MaxSpeedStr +
18505 "km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr + Status +
'\n' +
18506 "Additional delay here of 1 minute\nNext: " +
18511 TrainStatusFloat = HeadCode +
": " + Train.
TrainDataEntryPtr->
Description + ServiceReferenceInfo +
'\n' +
"Maximum train speed " + MaxSpeedStr +
18512 "km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr + Status +
'\n' +
18513 "Additional delay here of " + AnsiString(
int(Train.
NewDelay)) +
" minutes\nNext: " +
18518 TrainStatusFloat = HeadCode +
": " + Train.
TrainDataEntryPtr->
Description + ServiceReferenceInfo +
'\n' +
"Maximum train speed " + MaxSpeedStr +
18519 "km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr + Status +
'\n' +
"Next: " +
18525 TrainStatusFloat = HeadCode +
": " + Train.
TrainDataEntryPtr->
Description + ServiceReferenceInfo +
'\n' +
"Maximum train speed " + MaxSpeedStr +
18526 "km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr + Status +
'\n' +
"Next timetabled action: " +
18531 TrainStatusFloat = HeadCode +
": " + Train.
TrainDataEntryPtr->
Description + ServiceReferenceInfo +
'\n' +
"Maximum train speed " + MaxSpeedStr +
18532 "km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr + Status +
": " +
18533 CurrSpeedStr.FormatFloat(FormatNoDPStr, CurrSpeed) +
"km/h" +
'\n' +
"Next timetabled action: " + NextStopStr;
18536 return(TrainStatusFloat);
18615 InfoPanel->Caption =
"PRE-START: Route setting in progress";
18619 InfoPanel->Caption =
"OPERATING: Route setting in progress";
18742 bool Manual =
false;
18791 throw Exception(
"Failed to find a route at LC position HLoc = " + (AnsiString)H +
" VLoc = " + (AnsiString)V);
18796 if(RouteNumber > -1)
18830 bool SaveRailwayButtonsFlag =
true;
18839 SaveRailwayButtonsFlag =
false;
18857 SaveRailwayButtonsFlag =
false;
18865 SaveRailwayButtonsFlag =
false;
18916 bool ZoomFlag =
true, HomeFlag =
true, NewHomeFlag =
true, ScreenLeftFlag =
true, ScreenRightFlag =
true, ScreenUpFlag =
true, ScreenDownFlag =
true,
18917 TrackBuildPanelEnabledFlag =
true, PrefDirPanelEnabledFlag =
true, OperatingPanelEnabledFlag =
true, TimetablePanelEnabledFlag =
true;
18919 AnsiString TrackBuildPanelLabelCaptionStr =
"Build/modify";
18920 AnsiString PrefDirPanelLabelCaptionStr =
"Preferred direction selection";
18921 AnsiString OperatingPanelLabelCaptionStr =
"Operation";
18922 AnsiString TimetablePanelLabelCaptionStr =
"Timetable editor";
18929 ScreenLeftFlag =
false;
18933 ScreenRightFlag =
false;
18937 ScreenUpFlag =
false;
18941 ScreenDownFlag =
false;
18949 ScreenLeftFlag =
false;
18953 ScreenRightFlag =
false;
18957 ScreenUpFlag =
false;
18961 ScreenDownFlag =
false;
18968 NewHomeFlag =
false;
18969 ScreenLeftFlag =
false;
18970 ScreenRightFlag =
false;
18971 ScreenUpFlag =
false;
18972 ScreenDownFlag =
false;
18977 TrackBuildPanelEnabledFlag =
false;
18978 TrackBuildPanelLabelCaptionStr =
"Disabled";
18979 PrefDirPanelEnabledFlag =
false;
18980 PrefDirPanelLabelCaptionStr =
"Disabled";
18981 OperatingPanelEnabledFlag =
false;
18982 OperatingPanelLabelCaptionStr =
"Disabled";
18983 TimetablePanelEnabledFlag =
false;
18984 TimetablePanelLabelCaptionStr =
"Disabled";
18994 OperatingPanelEnabledFlag =
false;
18995 OperatingPanelLabelCaptionStr =
"Disabled";
18998 NewHomeFlag =
false;
18999 ScreenLeftFlag =
false;
19000 ScreenRightFlag =
false;
19001 ScreenUpFlag =
false;
19002 ScreenDownFlag =
false;
19015 NewHomeFlag =
false;
19016 ScreenLeftFlag =
false;
19017 ScreenRightFlag =
false;
19018 ScreenUpFlag =
false;
19019 ScreenDownFlag =
false;
19025 NewHomeFlag =
false;
19026 ScreenLeftFlag =
false;
19027 ScreenRightFlag =
false;
19028 ScreenUpFlag =
false;
19029 ScreenDownFlag =
false;
19036 NewHomeFlag =
false;
19037 ScreenLeftFlag =
false;
19038 ScreenRightFlag =
false;
19039 ScreenUpFlag =
false;
19040 ScreenDownFlag =
false;
19079 if(ScreenRightFlag)
19103 if(OperatingPanelEnabledFlag)
19111 if(TrackBuildPanelEnabledFlag)
19119 if(PrefDirPanelEnabledFlag)
19127 if(TimetablePanelEnabledFlag)
19150 bool CallOnValid =
false;
19156 CallOnValid =
true;
19251 Screen->Cursor = TCursor(-2);
19295 Caption =
"Railway: New railway under development";
19299 Caption =
"Railway: " +
RailwayTitle +
" under development";
19394 TFont *TempFont =
new TFont;
19396 TempFont->Style.Clear();
19397 TempFont->Name =
"MS Sans Serif";
19398 TempFont->Size = 10;
19400 TempFont->Charset = (TFontCharset)(0);
19508 if(NonPrefDirChangesMade)
19534 AnsiString CurrentDateTimeStr =
"", TimetableTimeStr =
"", SessionFileStr =
"";
19535 Screen->Cursor = TCursor(-11);
19536 CurrentDateTimeStr = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
19539 TimetableTimeStr = TimetableTimeStr.SubString(1, 2) +
'.' + TimetableTimeStr.SubString(4, 2) +
'.' + TimetableTimeStr.SubString(7, 2);
19542 SessionFileStr =
LoadSessionDialog->InitialDir +
"\\Session " + CurrentDateTimeStr +
"; Timetable time " + TimetableTimeStr +
"; " +
RailwayTitle +
19544 std::ofstream SessionFile(SessionFileStr.c_str());
19545 if(!(SessionFile.fail()))
19587 SessionFile.close();
19588 DeleteFile(SessionFileStr);
19589 Screen->Cursor = TCursor(-2);
19696 SessionFile.close();
19707 Screen->Cursor = TCursor(-2);
19710 catch(
const Exception &e)
19713 Screen->Cursor = TCursor(-2);
19745 Screen->Cursor = TCursor(-11);
19750 if(!(SessionFile.fail()))
19757 int LastCharBeforeFloat = TempString.LastDelimiter(
'*');
19758 if((LastCharBeforeFloat == 0) || (LastCharBeforeFloat == TempString.Length()))
19765 AnsiString FloatStr = TempString.SubString(LastCharBeforeFloat + 1, TempString.Length() - LastCharBeforeFloat);
19781 bool GraphicsFollow =
false;
19797 SessionFile.close();
19798 Screen->Cursor = TCursor(-2);
19799 ShowMessage(
"Corruption in preferred direction section of the session file, session can't be loaded");
19807 SessionFile.close();
19808 Screen->Cursor = TCursor(-2);
19809 ShowMessage(
"Corruption in route section of the session file, session can't be loaded");
19821 if(TempString ==
"***BarriersDownVector***")
19829 SessionFile.close();
19830 Screen->Cursor = TCursor(-2);
19831 ShowMessage(
"Unable to load timetable section of the session file, session can't be loaded");
19838 SessionFile.close();
19839 Screen->Cursor = TCursor(-2);
19840 throw Exception(
"TimetableTitle null in LoadSession");
19858 ShowMessage(
"Performance logfile failed to open, logs won't be saved. Ensure that there is a folder named " +
PERFLOG_DIR_NAME +
19859 " in the folder where the 'Railway.exe' program file resides");
19865 SessionFile.get(TempChar);
19866 while(!SessionFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
19868 SessionFile.get(TempChar);
19870 if(SessionFile.eof())
19874 SessionFile.close();
19875 goto FINISHEDLOADING;
19885 double PowerDouble;
19897 SessionFile.get(TempChar);
19898 while(!SessionFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
19900 SessionFile.get(TempChar);
19902 if(SessionFile.eof())
19904 SessionFile.close();
19905 goto FINISHEDLOADING;
19907 if((TempChar !=
'0') && (TempChar !=
'1'))
19909 throw Exception(
"TempChar value = " + AnsiString(TempChar) +
", should be 0 or 1");
19912 if(TempChar ==
'0')
19920 SessionFile.get(TempChar);
19921 while(!SessionFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
19923 SessionFile.get(TempChar);
19925 if(SessionFile.eof())
19927 SessionFile.close();
19928 goto FINISHEDLOADING;
19931 TempString = TempChar;
19932 SessionFile.get(TempChar);
19933 while((TempChar !=
'\n') && (TempChar !=
'\0'))
19935 TempString = TempString + TempChar;
19936 SessionFile.get(TempChar);
19947 SessionFile.get(TempChar);
19948 while(!SessionFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
19950 SessionFile.get(TempChar);
19952 if(SessionFile.eof())
19954 SessionFile.close();
19955 goto FINISHEDLOADING;
19958 TempString = TempChar;
19959 SessionFile.get(TempChar);
19960 while((TempChar !=
'\n') && (TempChar !=
'\0'))
19962 TempString = TempString + TempChar;
19963 SessionFile.get(TempChar);
19968 while(!SessionFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
19970 SessionFile.get(TempChar);
19972 if(SessionFile.eof())
19974 SessionFile.close();
19975 goto FINISHEDLOADING;
19978 TempString = TempChar;
19979 while(TempString !=
'E')
19981 SessionFile.get(TempChar);
19982 while((TempChar !=
'\n') && (TempChar !=
'\0'))
19984 TempString = TempString + TempChar;
19985 SessionFile.get(TempChar);
19993 SessionFile.get(TempChar);
19994 TempString = TempChar;
19995 while((TempChar ==
'\n') || (TempChar ==
'\0'))
19997 SessionFile.get(TempChar);
19998 TempString = TempChar;
20005 SessionFile.get(TempChar);
20006 while(!SessionFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
20008 SessionFile.get(TempChar);
20010 if(SessionFile.eof())
20012 SessionFile.close();
20013 goto FINISHEDLOADING;
20016 TempString = TempChar;
20017 while(TempString !=
'E')
20019 SessionFile.get(TempChar);
20020 while((TempChar !=
'\n') && (TempChar !=
'\0'))
20022 TempString = TempString + TempChar;
20023 SessionFile.get(TempChar);
20028 SessionFile.get(TempChar);
20029 TempString = TempChar;
20030 while((TempChar ==
'\n') || (TempChar ==
'\0'))
20032 SessionFile.get(TempChar);
20033 TempString = TempChar;
20040 SessionFile.get(TempChar);
20041 while(!SessionFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
20043 SessionFile.get(TempChar);
20045 if(SessionFile.eof())
20047 SessionFile.close();
20048 goto FINISHEDLOADING;
20052 while((TempChar !=
'\n') && (TempChar !=
'\0'))
20054 TempString = TempString + TempChar;
20055 SessionFile.get(TempChar);
20072 SessionFile.close();
20076 if(SessionFile.is_open())
20078 SessionFile.close();
20115 ShowMessage(
"Session file integrity check failed, unable to load " +
LoadSessionDialog->FileName);
20117 Screen->Cursor = TCursor(-2);
20121 catch(
const Exception &e)
20123 if((e.Message.Pos(
"esource") > 0) || (e.Message.Pos(
"arameter") > 0))
20125 Screen->Cursor = TCursor(-2);
20136 UnicodeString MessageStr =
20137 "Insufficient memory available to load the file, and partial load likely to be corrupt. Application will terminate. Try loading the session as the first action after reloading the program.";
20139 Application->MessageBox(MessageStr.c_str(), L
"Out of memory", MB_OK | MB_ICONERROR);
20140 Application->Terminate();
20145 Screen->Cursor = TCursor(-2);
20219 if(OpMode ==
"PreStart")
20282 AnsiString OpMode =
"";
20289 else if((OpMode !=
"PreStart") && (OpMode !=
"NotPreStart"))
20518 SessionFile.close();
20519 SessionFile.open(SessionFileStr.c_str(), std::ios_base::app | std::ios_base::binary);
20533 ShowMessage(
"Failed to open temporary timetable file. Unable to save the session");
20539 char *Buffer =
new char[10000];
20544 BytesRead = FileRead(Handle, Buffer, 10000);
20545 SessionFile.write(Buffer, BytesRead);
20546 if(BytesRead < 10000)
20554 SessionFile.close();
20555 SessionFile.open(SessionFileStr.c_str(), std::ios_base::app | std::ios_base::out);
20579 if(!FileExists(TimetableFileName))
20585 ErrorFile.open(ErrorFileStr.c_str(), std::ios_base::app | std::ios_base::binary);
20587 int Handle = FileOpen(TimetableFileName, fmOpenRead);
20594 Handle = FileOpen(TimetableFileName, fmOpenRead);
20604 char *Buffer =
new char[10000];
20609 BytesRead = FileRead(Handle, Buffer, 10000);
20610 ErrorFile.write(Buffer, BytesRead);
20611 if(BytesRead < 10000)
20620 ErrorFile.open(ErrorFileStr.c_str(), std::ios_base::app | std::ios_base::out);
20648 int TempTTFileNumber = 0;
20650 while(FileExists(
CurDir +
"\\TmpTT" + AnsiString(TempTTFileNumber) +
".tmp"))
20652 TempTTFileNumber++;
20660 if(!TTBFile.fail())
20662 char *Buffer =
new char[10000];
20663 char TempChar = (char)(SessionFile.peek());
20664 if(TempChar ==
'\n')
20666 SessionFile.get(TempChar);
20668 if(!SessionFile.getline(Buffer, 10000,
'\0'))
20677 for(
int x = 0; x < 10000; x++)
20679 if(Buffer[x] !=
'\0')
20688 while(AnsiString(Buffer) !=
"***End***")
20690 TTBFile.write(Buffer, Count);
20691 TTBFile.write(&Zero, 1);
20693 if(!SessionFile.getline(Buffer, 10000,
'\0'))
20702 for(
int x = 0; x < 10000; x++)
20704 if(Buffer[x] !=
'\0')
20718 bool GiveMessagesFalse =
false;
20719 bool CheckLocationsExistInRailwayTrue =
true;
20722 std::ifstream TTBLFile(
TempTTFileName.c_str(), std::ios_base::binary);
20723 if(TTBLFile.is_open())
20725 bool SessionFileTrue =
true;
20756 for(
int x = 0; x < NumberOfTrainEntries; x++)
20764 for(
int y = 0; y < NumberOfTrains; y++)
20789 AnsiString OutString;
20796 while(OutString !=
"***End***")
20805 if(SessionFile.fail())
20810 int NumberOfTrainEntries;
20817 for(
int x = 0; x < NumberOfTrainEntries; x++)
20819 int NumberOfTrains;
20825 for(
int y = 0; y < NumberOfTrains; y++)
20855 bool EndOfFile =
false;
20857 char *TrainTimetableString =
new char[10000];
20861 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
20862 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
20869 AnsiString OneLine(TrainTimetableString);
20870 bool FinalCallTrue =
true;
20872 CheckLocationsExistInRailway))
20874 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
20875 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
20878 throw Exception(
"Timetable FinalCall error - no start time on own line, Count = 0");
20880 OneLine = AnsiString(TrainTimetableString);
20886 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
20887 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
20894 OneLine = AnsiString(TrainTimetableString);
20900 throw Exception(
"Timetable FinalCall error in processing one timetable line, Count = " + AnsiString(Count));
20902 if(EndOfFile && (Count < 2))
20905 throw Exception(
"Timetable FinalCall error - too few or no relevant entries, Count = " + AnsiString(Count));
20910 delete[]TrainTimetableString;
20911 bool TwoLocationFlag;
20919 ShowMessage(
"Timetable secondary integrity check failed - unable to load");
20956 bool EndOfFile =
false;
20958 char *TrainTimetableString =
new char[10000];
20962 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
20963 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
20970 AnsiString OneLine(TrainTimetableString);
20971 bool FinalCallTrue =
true;
20973 CheckLocationsExistInRailway))
20975 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
20976 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
20979 throw Exception(
"Timetable FinalCall error - no start time on own line, Count = 0");
20981 OneLine = AnsiString(TrainTimetableString);
20987 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
20988 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
20995 OneLine = AnsiString(TrainTimetableString);
21001 throw Exception(
"Timetable FinalCall error in processing one timetable line, Count = " + AnsiString(Count));
21003 if(EndOfFile && (Count < 2))
21006 throw Exception(
"Timetable FinalCall error - too few or no relevant entries, Count = " + AnsiString(Count));
21011 delete[]TrainTimetableString;
21012 bool TwoLocationFlag;
21023 else if(TwoLocationFlag)
21025 AnsiString AllServices =
"", Suffix =
"";
21035 AllServices = AllServices + *TLLIt +
", ";
21041 Suffix =
"(more than 5, first 5 are) ";
21045 TwoLocationNameLabel->Caption =
"The following services have two or more locations with the same name without a change of\n"
21046 "direction between them. If this isn't intended then please correct them.\n\n"
21047 "Before ticking the check box please be sure that all services are correct.\n\n"
21048 "Services: " + Suffix +
" " + AllServices;
21052 TwoLocationNameLabel->Caption =
"The following service has two or more locations with the same name without a change of\n"
21053 "direction between them. If this isn't intended then please correct it.\n\n"
21054 "Service: " + AllServices;
21084 std::ifstream InFile(FileName.c_str());
21086 int NumberOfActiveElements;
21087 bool GraphicsFollow =
false;
21089 if(InFile.is_open())
21236 if((TempString !=
"***BarriersDownVector***") && (TempString !=
"***Timetable***"))
21242 if(TempString ==
"***BarriersDownVector***")
21286 InFile.open(FileName.c_str());
21287 if(InFile.is_open())
21308 bool GraphicsFollow =
false;
21429 if((TempString !=
"***BarriersDownVector***") && (TempString !=
"***Timetable***"))
21435 if(TempString ==
"***BarriersDownVector***")
21514 InFile.get(TempChar);
21515 while(!InFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
21517 InFile.get(TempChar);
21548 double PowerDouble;
21578 AnsiString TempString =
"", Line1 =
"", Line2 =
"", Line3 =
"", Line4 =
"", Line5 =
"";
21579 char *Buffer =
new char[1000];
21582 InFile.get(TempChar);
21583 InFile.getline(Buffer, 1000);
21584 TempString = AnsiString(Buffer);
21585 if(TempString ==
"***End of performance file***")
21592 while(TempString !=
"***End of performance file***")
21597 InFile.getline(Buffer, 1000);
21598 TempString = AnsiString(Buffer);
21610 AnsiString TempString =
"";
21613 InFile.get(TempChar);
21614 if(TempChar !=
'\n')
21624 while(TempString !=
"***End of performance file***")
21645 AnsiString OneLine = Text.SubString(1, Text.Pos(
'\x0D'));
21646 while((OneLine.Length() > 0) && OneLine[OneLine.Length()] <
' ')
21648 OneLine.SetLength(OneLine.Length() - 1);
21650 Text = Text.SubString(Text.Pos(
'\x0D'), Text.Length());
21651 while((Text.Length() > 0) && Text[1] <
' ')
21653 Text = Text.SubString(2, (Text.Length() - 1));
21655 OutFile << OneLine.c_str() <<
'\n';
21676 InfoPanel->Caption =
"PRE-START: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
21680 InfoPanel->Caption =
"OPERATING: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
21693 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
21697 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
21710 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
21714 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
21727 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
21731 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
21745 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
21749 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
21776 InfoPanel->Caption =
"Left click screen to zoom in at that position";
21781 InfoPanel->Caption =
"PAUSED: Railway state changes disabled";
21859 Screen->Cursor = TCursor(-11);
21860 AnsiString ErrorFileStr =
CurDir +
"\\errorlog.err";
21861 std::ofstream ErrorFile(ErrorFileStr.c_str());
21863 if(!(ErrorFile.fail()))
21866 int ScreenX = Mouse->CursorPos.x -
MainScreen->ClientOrigin.x;
21867 int ScreenY = Mouse->CursorPos.y -
MainScreen->ClientOrigin.y;
21868 AnsiString MouseStr =
"Posx: " + AnsiString(ScreenX) +
"; Posy: " + AnsiString(ScreenY);
21875 ErrorFile << Item.c_str() <<
'\n';
21882 ErrorFile << Item.c_str() <<
'\n';
22059 Screen->Cursor = TCursor(-2);
22076 int TempTTFileNumber = 0;
22078 while(FileExists(
CurDir +
"\\TmpTT" + AnsiString(TempTTFileNumber) +
".tmp"))
22080 TempTTFileNumber++;
22083 int InHandle = FileOpen(InFileName, fmOpenRead);
22086 while(InHandle < 0)
22088 InHandle = FileOpen(InFileName, fmOpenRead);
22093 ShowMessage(
"Failed to open timetable file, make sure it's spelled correctly, it exists and isn't open in another application");
22101 while(OutHandle < 0)
22108 ShowMessage(
"Failed to save temporary timetable file, sessions can't be saved - try again, may only be a temporary problem");
22109 FileClose(InHandle);
22114 int CountIn, CountOut;
22115 char *Buffer =
new char[10000];
22119 CountIn = FileRead(InHandle, Buffer, 10000);
22120 CountOut = FileWrite(OutHandle, Buffer, CountIn);
22121 if(CountOut != CountIn)
22123 ShowMessage(
"Error in writing to the temporary timetable file, sessions can't be saved - try again, may only be a temporary problem");
22125 FileClose(InHandle);
22126 FileClose(OutHandle);
22130 if(CountIn < 10000)
22136 FileClose(InHandle);
22137 FileClose(OutHandle);
22182 int VarElements = 0;
22183 bool NamedLocPresent =
false;
22191 throw Exception(
"Error - failed to find track element at " + AnsiString(TE.
HLoc) +
" & " + AnsiString(TE.
VLoc) +
" in SetLengths");
22200 NamedLocPresent =
true;
22205 if(SpeedLimit != -1)
22212 if(SpeedLimit != -1)
22223 if((NamedLocPresent) && (VarElements > 0) && ((Distance / VarElements) < 50))
22227 ShowMessage(
"Note: Named location elements are quite short. If they are too short the simulation might be too unrealistic.\n\nThis message will not be shown again.");
22231 if((NamedLocPresent) && (VarElements > 0) && ((Distance / VarElements) > 200))
22235 ShowMessage(
"Note: Named location elements are quite long. If they are too long the simulation might be too unrealistic.\n\nThis message will not be shown again.");
22239 if((VarElements * 10) > Distance)
22241 ShowMessage(
"Required distance is less than the minimum, will set each element to the minimum (10m)");
22242 Distance = (VarElements * 10);
22244 if(VarElements == 0)
22247 ShowMessage(
"No elements selected");
22252 int RemainingDistance = Distance, RemainingVarElements = VarElements, NextLength = RemainingDistance / VarElements;
22260 if(NextLength < 10)
22286 RemainingDistance -= NextLength;
22287 RemainingVarElements--;
22288 if(RemainingVarElements > 0)
22290 NextLength = RemainingDistance / RemainingVarElements;
22318 ShowMessage(
"Nothing to save!");
22324 SaveRailwayDialog->Filter =
"Development file (*.dev)|*.dev|Railway file (*.rly)|*.rly";
22337 Screen->Cursor = TCursor(-11);
22339 AnsiString Extension =
"";
22347 if(!(VecFile.fail()))
22375 if((LastChar ==
'y') || (LastChar ==
'Y'))
22404 ShowMessage(
"File open failed prior to save");
22409 ShowMessage(
"Can't save: extension must be either '.dev', or '.rly' with railway ready for operation");
22411 Screen->Cursor = TCursor(-2);
22448 System::WideChar ValidityBuffer[14];
22449 Clipboard()->GetTextBuf(ValidityBuffer, 14);
22451 Clipboard()->Close();
22508 catch(
const EClipboardException &e)
22567 bool TextFound =
false;
22592 AnsiString(VPos) +
"," + AnsiString((
short)UseEnteredPosition));
22593 int VPosHi, VPosLo, TextPosHi, TextPosLo;
22596 if(!UseEnteredPosition)
22603 int Depth = abs(Font->Height);
22604 TextPosHi = VPosHi + 20;
22605 TextPosLo = VPosLo - Depth - 4;
22608 if(TextPosLo >= ScreenPosLo)
22612 else if(TextPosHi < ScreenPosHi)
22618 VPos = ScreenPosLo + 288;
22796 catch(
const Exception &e)
22850 AnsiString OpTimeToActDisplay;
22851 AnsiString OpTimeToActString;
22852 AnsiString HeadCode;
22853 float OpTimeToActFloat;
22865 HeadCode = HCandTrainPosParam.first;
22866 if(OpTimeToActFloat < 0.25)
22868 OpTimeToActString =
"NOW";
22870 else if(OpTimeToActFloat < 1)
22872 OpTimeToActString =
"<1";
22876 OpTimeToActString = AnsiString(floor(OpTimeToActFloat));
22878 if(OpTimeToActFloat < 60)
22880 OpTimeToActDisplay = HeadCode + AnsiString(
'\t') + OpTimeToActString;
22881 OAListBox->Items->Add(OpTimeToActDisplay);
22951 TPicture *PicPtr =
new TPicture;
22953 UGME.second = PicPtr;
22964 catch(
const EInvalidGraphic &e)
22967 "Incorrect file format, the file can't be loaded.\nEnsure that the file you want is a valid graphic file with extension .bmp, .gif, .jpg, or .png");
22970 catch(
const Exception &e)
22985 std::wstringstream wss;
22988 wss <<
"RlyClpBrdCopy\n";
22992 wss <<
"RlyClpBrd_Cut\n";
22997 wss << TTVIt->SpeedTag;
22999 for(
int AnsLen = 0; AnsLen <= TTVIt->ActiveTrackElementName.Length(); AnsLen++)
23001 if((TTVIt->ActiveTrackElementName).c_str()[AnsLen] !=
'\0')
23003 wss << (TTVIt->ActiveTrackElementName).c_str()[AnsLen];
23010 for(
int AnsLen = 0; AnsLen <= TTVIt->ElementID.Length(); AnsLen++)
23012 if((TTVIt->ElementID).c_str()[AnsLen] !=
'\0')
23014 wss << (TTVIt->ElementID).c_str()[AnsLen];
23021 for(
int AnsLen = 0; AnsLen <= TTVIt->LocationName.Length(); AnsLen++)
23023 if((TTVIt->LocationName).c_str()[AnsLen] !=
'\0')
23025 wss << (TTVIt->LocationName).c_str()[AnsLen];
23032 wss << TTVIt->CallingOnSet;
23034 wss << TTVIt->LCPlotted;
23036 wss << TTVIt->TempTrackMarker01;
23038 wss << TTVIt->TempTrackMarker23;
23040 wss << TTVIt->Attribute;
23042 wss << TTVIt->Conn[0];
23044 wss << TTVIt->Conn[1];
23046 wss << TTVIt->Conn[2];
23048 wss << TTVIt->Conn[3];
23050 wss << TTVIt->ConnLinkPos[0];
23052 wss << TTVIt->ConnLinkPos[1];
23054 wss << TTVIt->ConnLinkPos[2];
23056 wss << TTVIt->ConnLinkPos[3];
23058 wss << TTVIt->HLoc;
23060 wss << TTVIt->VLoc;
23062 wss << TTVIt->Length01;
23064 wss << TTVIt->Length23;
23066 wss << TTVIt->SpeedLimit01;
23068 wss << TTVIt->SpeedLimit23;
23070 wss << TTVIt->StationEntryStopLinkPos1;
23072 wss << TTVIt->StationEntryStopLinkPos2;
23074 wss << TTVIt->TrainIDOnElement;
23076 wss << TTVIt->TrainIDOnBridgeTrackPos01;
23078 wss << TTVIt->TrainIDOnBridgeTrackPos23;
23080 wss << int(TTVIt->SigAspect);
23083 wss <<
"$$$" <<
'\n';
23089 for(
int AnsLen = 0; AnsLen <= TTVIt->TextString.Length(); AnsLen++)
23091 if((TTVIt->TextString).c_str()[AnsLen] !=
'\0')
23093 wss << (TTVIt->TextString).c_str()[AnsLen];
23100 wss << TTVIt->HPos;
23102 wss << TTVIt->VPos;
23104 for(
int AnsLen = 0; AnsLen <= AnsiString(TTVIt->Font->Name).Length(); AnsLen++)
23106 if(AnsiString(TTVIt->Font->Name).c_str()[AnsLen] !=
'\0')
23108 wss << AnsiString(TTVIt->Font->Name).c_str()[AnsLen];
23115 wss << TTVIt->Font->Size;
23117 if((TTVIt->Font->Color < 0) || (TTVIt->Font->Color > 0xFFFFFF))
23123 wss << int(TTVIt->Font->Color) <<
'\n';
23125 wss << int(TTVIt->Font->Charset) <<
'\n';
23128 wss <<
"$$$" <<
'\n';
23139 wss <<
"$$$" <<
'\n';
23148 wss << PDVIt->GetTrackVectorPosition();
23150 wss << PDVIt->GetHLoc();
23152 wss << PDVIt->GetVLoc();
23154 wss << PDVIt->GetELink();
23156 wss << PDVIt->GetELinkPos();
23158 wss << PDVIt->GetXLink();
23160 wss << PDVIt->GetXLinkPos();
23162 wss << PDVIt->GetEXNumber();
23166 wss <<
"$$$" <<
'\n';
23169 Clipboard()->Clear();
23170 Clipboard()->SetTextBuf(&(wss.str()[0]));
23171 Clipboard()->Close();
23176 catch(
const EClipboardException &e)
23183 catch(
const Exception &e)
23198 ValidResult =
false;
23199 System::WideChar *SelectVectorBuffer =
new System::WideChar[4000000];
23200 int StreamSize = 0;
23201 StreamSize = Clipboard()->GetTextBuf(SelectVectorBuffer, 4000000);
23202 Clipboard()->Clear();
23203 Clipboard()->Close();
23204 if(StreamSize < 14)
23209 std::wstringstream wss;
23210 wss << SelectVectorBuffer;
23211 ClpBrdValid = AnsiString(SelectVectorBuffer).SubString(1, 13);
23213 delete[]SelectVectorBuffer;
23220 int MarkerCounter = 0;
23222 wchar_t LineString[1000];
23227 wss.getline(LineString, 100);
23234 wss.getline(LineString, 100);
23235 if(AnsiString(LineString) ==
"$$$")
23242 wss.getline(LineString, 100);
23244 wss.getline(LineString, 100);
23246 wss.getline(LineString, 100);
23249 wss.getline(LineString, 100);
23251 wss.getline(LineString, 100);
23252 TE.
LCPlotted = AnsiString(LineString).ToInt();
23253 wss.getline(LineString, 100);
23255 wss.getline(LineString, 100);
23258 wss.getline(LineString, 100);
23259 TE.
Attribute = AnsiString(LineString).ToInt();
23260 wss.getline(LineString, 100);
23261 TE.
Conn[0] = AnsiString(LineString).ToInt();
23262 wss.getline(LineString, 100);
23263 TE.
Conn[1] = AnsiString(LineString).ToInt();
23264 wss.getline(LineString, 100);
23265 TE.
Conn[2] = AnsiString(LineString).ToInt();
23266 wss.getline(LineString, 100);
23267 TE.
Conn[3] = AnsiString(LineString).ToInt();
23268 wss.getline(LineString, 100);
23269 TE.
ConnLinkPos[0] = AnsiString(LineString).ToInt();
23270 wss.getline(LineString, 100);
23271 TE.
ConnLinkPos[1] = AnsiString(LineString).ToInt();
23272 wss.getline(LineString, 100);
23273 TE.
ConnLinkPos[2] = AnsiString(LineString).ToInt();
23274 wss.getline(LineString, 100);
23275 TE.
ConnLinkPos[3] = AnsiString(LineString).ToInt();
23276 wss.getline(LineString, 100);
23277 TE.
HLoc = AnsiString(LineString).ToInt();
23278 wss.getline(LineString, 100);
23279 TE.
VLoc = AnsiString(LineString).ToInt();
23280 wss.getline(LineString, 100);
23281 TE.
Length01 = AnsiString(LineString).ToInt();
23282 wss.getline(LineString, 100);
23283 TE.
Length23 = AnsiString(LineString).ToInt();
23284 wss.getline(LineString, 100);
23286 wss.getline(LineString, 100);
23288 wss.getline(LineString, 100);
23290 wss.getline(LineString, 100);
23292 wss.getline(LineString, 100);
23294 wss.getline(LineString, 100);
23296 wss.getline(LineString, 100);
23299 wss.getline(LineString, 100);
23300 int temp = AnsiString(LineString).ToInt();
23321 SelectTrackMapKeyPair.first = TE.
HLoc;
23322 SelectTrackMapKeyPair.second = TE.
VLoc;
23323 SelectTrackMapEntry.first = SelectTrackMapKeyPair;
23325 SelectTrackMap.insert(SelectTrackMapEntry);
23330 AnsiString FontName;
23331 int FontSize, FontColour, FontCharset, FontStyle;
23334 wss.getline(LineString, 1000);
23335 if(AnsiString(LineString) ==
"$$$")
23343 wss.getline(LineString, 1000);
23344 TI.
HPos = AnsiString(LineString).ToInt();
23345 wss.getline(LineString, 1000);
23346 TI.
VPos = AnsiString(LineString).ToInt();
23347 wss.getline(LineString, 1000);
23348 FontName = AnsiString(LineString).c_str();
23349 wss.getline(LineString, 1000);
23350 FontSize = AnsiString(LineString).ToInt();
23351 wss.getline(LineString, 1000);
23352 FontColour = AnsiString(LineString).ToInt();
23353 wss.getline(LineString, 1000);
23354 FontCharset = AnsiString(LineString).ToInt();
23355 wss.getline(LineString, 1000);
23356 FontStyle = AnsiString(LineString).ToInt();
23358 TFont *NewFont =
new TFont;
23359 NewFont->Name = FontName;
23360 NewFont->Size = FontSize;
23361 NewFont->Color =
static_cast<TColor
>(FontColour);
23362 NewFont->Charset = FontCharset;
23369 wss.getline(LineString, 100);
23370 SelectBitmap->Height = AnsiString(LineString).ToInt();
23371 wss.getline(LineString, 100);
23373 wss.getline(LineString, 100);
23374 SelectRect.left = AnsiString(LineString).ToInt();
23375 wss.getline(LineString, 100);
23376 SelectRect.top = AnsiString(LineString).ToInt();
23377 wss.getline(LineString, 100);
23378 if(AnsiString(LineString) ==
"$$$")
23385 int TempTVPos, TempHLoc, TempVLoc, TempELink, TempELinkPos, TempXLink, TempXLinkPos, TempEXNumber, ATVecPos;
23390 wss.getline(LineString, 100);
23391 if(AnsiString(LineString) ==
"$$$")
23397 TempTVPos = AnsiString(LineString).ToInt();
23398 wss.getline(LineString, 100);
23399 TempHLoc = AnsiString(LineString).ToInt();
23400 wss.getline(LineString, 100);
23401 TempVLoc = AnsiString(LineString).ToInt();
23402 wss.getline(LineString, 100);
23403 TempELink = AnsiString(LineString).ToInt();
23404 wss.getline(LineString, 100);
23405 TempELinkPos = AnsiString(LineString).ToInt();
23406 wss.getline(LineString, 100);
23407 TempXLink = AnsiString(LineString).ToInt();
23408 wss.getline(LineString, 100);
23409 TempXLinkPos = AnsiString(LineString).ToInt();
23410 wss.getline(LineString, 100);
23411 TempEXNumber = AnsiString(LineString).ToInt();
23420 TempPrefDirElement.
SetELink(TempELink);
23422 TempPrefDirElement.
SetXLink(TempXLink);
23429 if(MarkerCounter == 4)
23431 ValidResult =
true;
23436 catch(
const EClipboardException &e)
23438 ValidResult =
false;
23442 catch(
const Exception &e)
23444 ValidResult =
false;
23483 DelayMenu->Caption =
"Moderate delays";
23535 MPHPGeneralLabel->Caption =
"Complete the boxes and press 'Enter' for each.";
23544 catch(
const EIdException &e)
23546 ShowMessage(
"MultiplayerHostSessionMenuItemClick " + e.Message);
23549 catch(
const Exception &e)
23587 bool RailwayFound =
false;
23596 RailwayFound =
true;
23602 ShowMessage(
"Can't find '" +
RailwayTitle +
"' in coupling file - please load an appropriate railway and timetable or a pre-start session file");
23609 int GridCount = 2; ;
23612 unsigned char x = 1;
23646 catch(
const EIdException &e)
23648 ShowMessage(
"MPHPLoadCouplingFileButtonClick " + e.Message);
23651 catch(
const Exception &e)
23676 catch(
const EIdException &e)
23678 ShowMessage(
"MPHPCancelButtonClick " + e.Message);
23681 catch(
const Exception &e)
23695 ShowMessage(
"We're off!");
23702 catch(
const EIdException &e)
23704 ShowMessage(
"MPHPStartButtonClick " + e.Message);
23707 catch(
const Exception &e)
23725 ShowMessage(
"Format should be 'a.b.c.d' where a, b, c, and d are numbers between 0 and 255.\n\nObtain the address from the host and enter exactly as given.");
23745 ShowMessage(
"Format should be 'a.b.c.d' where a, b, c, and d are numbers between 0 and 255.\n\nObtain the address from the host and enter exactly as given.");
23754 catch(
const EIdException &e)
23756 ShowMessage(
"MPHPOwnIPEditBoxKeyUp " + e.Message);
23759 catch(
const Exception &e)
23777 ShowMessage(
"Entry should be a number between 49152 and 59999.");
23797 ShowMessage(
"Entry should be a number between 49152 and 59999.");
23806 catch(
const EIdException &e)
23808 ShowMessage(
"MPHPOwnPortEditBoxKeyUp " + e.Message);
23811 catch(
const Exception &e)
23820 TSysLinkType LinkType)
23822 if(LinkType == sltURL)
23824 ::ShellExecute(Handle, NULL, Link.c_str(), NULL, NULL, SW_SHOWNORMAL);
23832 if(lower.first < higher.first)
23836 else if(lower.first > higher.first)
23840 else if(lower.second.first < higher.second.first)
23844 else if(lower.second.first > higher.second.first)
23848 else if(lower.second.second < higher.second.second)
23852 else return(
false);
23861 if(lower.first < higher.first)
23865 else if(lower.first > higher.first)
23869 else if(lower.second.first < higher.second.first)
23873 else if(lower.second.first > higher.second.first)
23877 else if(lower.second.second < higher.second.second)
23881 else if(lower.second.second > higher.second.second)
23885 else return(
false);
23897 AnsiString RailwayName1 =
"", RailwayName2 =
"", OneLine =
"", ExitID1 =
"", ExitID2 =
"";
23898 int HLoc1, HLoc2, VLoc1, VLoc2, CPos, NumRailways;
23903 std::ifstream TxtFile(FileName.c_str());
23904 AnsiString SyntaxError =
"Coupling file error - structure should consist of lines of 'R1; exit1ID; R2; exit2ID' and so on "
23905 "for all coupled exits, where R1 and R2 are railway names without the '.rly' extension, exit1ID is an "
23906 "exit ID in R1, and exit2ID is an exit ID in R2";
23909 ShowMessage(
"Can't find the coupling file. Please make sure it's located in the directory selected and has a .txt extension");
23913 while(!TxtFile.eof())
23917 ShowMessage(SyntaxError);
23922 if(TxtFile.eof() && (OneLine ==
""))
23926 if(OneLine.AnsiPos(
',') != 0)
23928 ShowMessage(SyntaxError);
23937 int DelimPos = OneLine.Pos(
';');
23940 ShowMessage(SyntaxError);
23947 RailwayName1 = OneLine.SubString(1, (DelimPos - 1));
23948 OneLine = OneLine.SubString(DelimPos + 1, OneLine.Length() - DelimPos);
23949 if(RailwayName1.LowerCase().SubString(RailwayName1.Length() - 3, 4) ==
".rly")
23951 RailwayName1 = RailwayName1.SubString(1, RailwayName1.Length() - 4);
23954 DelimPos = OneLine.Pos(
';');
23957 ShowMessage(SyntaxError);
23964 ExitID1 = OneLine.SubString(1, (DelimPos - 1));
23965 OneLine = OneLine.SubString(DelimPos + 1, OneLine.Length() - DelimPos);
23973 DelimPos = OneLine.Pos(
';');
23976 ShowMessage(SyntaxError);
23983 RailwayName2 = OneLine.SubString(1, (DelimPos - 1));
23984 OneLine = OneLine.SubString(DelimPos + 1, OneLine.Length() - DelimPos);
23985 if(RailwayName2.LowerCase().SubString(RailwayName2.Length() - 3, 4) ==
".rly")
23987 RailwayName2 = RailwayName2.SubString(1, RailwayName2.Length() - 4);
23992 ShowMessage(SyntaxError);
24007 AnsiCouplingPair1.first = RailwayName1;
24008 AnsiCouplingPair1.second = HVExitPair1;
24009 AnsiCouplingPair2.first = RailwayName2;
24010 AnsiCouplingPair2.second = HVExitPair2;
24011 AnsiCouplingMapEntry.first = AnsiCouplingPair1;
24012 AnsiCouplingMapEntry.second = AnsiCouplingPair2;
24014 AnsiCouplingMapEntry.first = AnsiCouplingPair2;
24015 AnsiCouplingMapEntry.second = AnsiCouplingPair1;
24034 int ListCounter = 1;
24037 if(ACMIt->first.first == *
RLIt)
24039 NumHVPair1.first = ListCounter;
24040 NumHVPair1.second = ACMIt->first.second;
24048 if(ACMIt->second.first == *
RLIt)
24050 NumHVPair2.first = ListCounter;
24051 NumHVPair2.second = ACMIt->second.second;
24066 DMEntry.first = CMIt->first;
24067 DMEntry.second = ServiceInfo;
24070 ShowMessage(
"File loaded successfully");
24080 AnsiString HString =
"", VString =
"";
24083 ShowMessage(
"Coupling file error - an exit ID is missing from the file");
24087 for(
int x = 1; x <= HVID.Length(); x++)
24090 if(((C <
'0') || (C >
'9')) && (C !=
'N') && (C !=
'-'))
24092 ShowMessage(
"Coupling file error - an exit ID contains illegal characters, can only include digits, '-' or 'N'");
24097 int DashPos = HVID.Pos(
'-');
24100 ShowMessage(
"Coupling file error - structure should consist of lines of 'R1, exit1 ID, R2, corresponding exit ID' and so on "
24101 "for all coupled exits, where R1 and R2 are railway names without the '.rly' extension");
24107 HString = HVID.SubString(1, DashPos - 1);
24108 VString = HVID.SubString(DashPos + 1, HVID.Length() - DashPos);
24109 if(HString[1] ==
'N')
24111 HString = HString.SubString(2, HString.Length() - 1);
24112 HVPair.first = -HString.ToInt();
24116 HVPair.first = HString.ToInt();
24118 if(VString[1] ==
'N')
24120 VString = VString.SubString(2, VString.Length() - 1);
24121 HVPair.second = -VString.ToInt();
24125 HVPair.second = VString.ToInt();
24138 bool Listed =
false, Available =
false, RetType =
false;
24155 else if(!Available)
24173 TCouplingMap::iterator CMIt;
24177 if(CMIt->first.first == PlayerNumber)
24186 return(Count * 10);
24199 UnicodeString Data =
"";
24200 UnicodeString PeerIP =
"";
24201 unsigned short PeerPort = 0;
24202 unsigned char marker;
24203 bool Found1 =
false, Found2 =
false;
24204 AnsiString PlayerRailwayName, PlayerUserName;
24206 UnicodeString Message1 =
"The railway doesn't appear in the coupled group - the host can advise which railways are valid";
24207 UnicodeString Message2 =
"The railway has already been allocated - the host can advise which are still available";
24209 HostBuffer.Length = 8192;
24210 HostBuffer.Length =
MPHostClient->ReceiveBuffer(HostBuffer, PeerIP, PeerPort, 10);
24213 if(HostBuffer.Length != 0)
24215 if(HostBuffer[0] ==
'1')
24218 bool FoundFlag =
false;
24219 for(
int x = 1; x < HostBuffer.Length; x++)
24221 if((HostBuffer[x] ==
';') && (x > 1) && (x < (HostBuffer.Length - 1)))
24232 for(
int x = 1; x < HostBuffer.Length; x++)
24234 if((HostBuffer[x] <
' ') || (HostBuffer[x] >
'~'))
24241 Data = BytesToString(HostBuffer);
24242 int DelimPos = Data.Pos(
';');
24243 PlayerUserName = Data.SubString(2, DelimPos - 2);
24244 PlayerRailwayName = Data.SubString(DelimPos + 1, Data.Length() - DelimPos);
24245 unsigned char PlayerNumber;
24246 if(!
RlyToNum(PlayerRailwayName, PlayerNumber))
24248 ShowMessage(
"Error in converting incoming information for player '" + PlayerUserName +
"', ask player to cancel and join again");
24257 UnicodeString RejectString = PlayerUserName +
" is asking to join with railway " + PlayerRailwayName +
". OK to join?";
24258 int button = Application->MessageBox(RejectString.c_str(), L
"Request", MB_YESNO);
24261 MPHostClient->SendBuffer(PeerIP, PeerPort, ToBytes(
"The host did not accept your request to join"));
24278 if(
InfoVector.at(x).RailwayName == PlayerRailwayName)
24287 if(!Found1 || !Found2)
24290 ShowMessage(
"Error in initial contact information for player '" + PlayerUserName +
"', ask player to cancel and join again");
24300 HVbuffer.Length = NumBytes;
24301 for(
int x = 0; x < NumBytes; x += 10)
24303 HVbuffer[x] = CMIt->first.first;
24304 HVbuffer[x + 1] = CMIt->first.second.first & 0x00FF;
24305 HVbuffer[x + 2] = (CMIt->first.second.first & 0xFF00) / 256;
24306 HVbuffer[x + 3] = CMIt->first.second.second & 0x00FF;
24307 HVbuffer[x + 4] = (CMIt->first.second.second & 0xFF00) / 256;
24309 HVbuffer[x + 5] = CMIt->second.first;
24310 HVbuffer[x + 6] = CMIt->second.second.first & 0x00FF;
24311 HVbuffer[x + 7] = (CMIt->second.second.first & 0xFF00) / 256;
24312 HVbuffer[x + 8] = CMIt->second.second.second & 0x00FF;
24313 HVbuffer[x + 9] = (CMIt->second.second.second & 0xFF00) / 256;
24324 if(ErrorNumber == 1)
24326 MPHostClient->SendBuffer(PeerIP, PeerPort, ToBytes(Message1));
24328 else if(ErrorNumber == 2)
24330 MPHostClient->SendBuffer(PeerIP, PeerPort, ToBytes(Message2));
24335 else if(HostBuffer[0] ==
'2')
24337 TDynamicMap::iterator DMIt, HMIt;
24346 HMIt->second = DMIt->second;
24350 ShowMessage(
"Failed to locate player information in host database for player '" + PlayerUserName +
"', ask player to cancel and join again");
24375 if(
InfoVector.at(x).UserName == PlayerUserName)
24382 if(!Found1 || !Found2)
24385 ShowMessage(
"Error in 'ready to begin' contact information for player '" + PlayerUserName +
"', ask player to cancel and join again");
24392 HVbuffer.Length = 22;
24393 UnicodeString Message =
"Await simulation start";
24394 HVbuffer = ToBytes(Message);
24398 bool AllReady =
true;
24411 else if(HostBuffer[0] ==
'3')
24413 for(
int x = 1; x < HostBuffer.Length; x++)
24415 if((HostBuffer[x] <
' ') || (HostBuffer[x] >
'~'))
24421 Data = BytesToString(HostBuffer);
24422 PlayerUserName = Data.SubString(2, Data.Length() - 1);
24424 HVbuffer.Length = 9;
24425 UnicodeString Message =
"Cancelled";
24426 HVbuffer = ToBytes(Message);
24429 unsigned char RlyUserNumber;
24430 if(!
UserToNum(PlayerUserName, RlyUserNumber))
24437 ShowMessage(
"Player '" + PlayerUserName +
"', has cancelled the join request");
24443 else if(HostBuffer[0] ==
'4')
24447 for(
int x = 1; x < HostBuffer.Length; x++)
24449 if((HostBuffer[x] <
' ') || (HostBuffer[x] >
'~'))
24455 Data = BytesToString(HostBuffer);
24456 PlayerUserName = Data.SubString(2, Data.Length() - 1);
24458 HVbuffer.Length = 13;
24459 UnicodeString Message =
"Start Session";
24460 HVbuffer = ToBytes(Message);
24467 else if(HostBuffer[0] ==
'5')
24469 TDynamicMap::iterator DMIt, HMIt;
24478 HMIt->second = DMIt->second;
24483 unsigned char RlyUserNumber;
24484 if(!
UserToNum(PlayerUserName, RlyUserNumber))
24490 bool LoadingFlag =
false;
24494 if(HMIt->first.first == RlyUserNumber)
24497 LoadingFlag =
true;
24499 if(LoadingFlag && (HMIt->first.first != RlyUserNumber))
24506 HVbuffer.Length = 8192;
24522 catch(
const EIdException &e)
24527 catch(
const Exception &e)
24548 MPCPLabel2->Caption =
"Complete the boxes and press 'Enter' for each.";
24549 MPCPLabel4->Caption =
"Joining request not yet sent";
24550 MPCPLabel7->Caption =
"Only click 'Send' when the host is ready - the host will";
24551 MPCPLabel8->Caption =
"advise by communicating outside the game.";
24552 MPCPLabel5->Caption =
"Host IP address (obtain from host)";
24553 MPCPLabel6->Caption =
"Host port number (obtain from host)";
24554 MPCPLabel3->Caption =
"Player name (2 to 4 characters)";
24586 catch(
const Exception &e)
24600 MPCPLabel2->Caption =
"Await host response then click 'Ready to begin'";
24601 MPCPLabel4->Caption =
"Awaiting host response";
24617 catch(
const Exception &e)
24647 catch(
const Exception &e)
24661 int button = Application->MessageBox(L
"This will transfer all timer controls to the host.\n\n Click 'Yes' to wait for the host to start the simulation.\n\nOK to proceed?", L
"Warning!", MB_YESNO | MB_ICONWARNING);
24687 catch(
const Exception &e)
24705 ShowMessage(
"Format should be 'a.b.c.d' where a, b, c, and d are numbers between 0 and 255.\n\nObtain the address from the host and enter exactly as given.");
24727 ShowMessage(
"Format should be 'a.b.c.d' where a, b, c, and d are numbers between 0 and 255.\n\nObtain the address from the host and enter exactly as given.");
24736 catch(
const Exception &e)
24755 ShowMessage(
"Entry should be a number between 49152 and 59999.\n\nObtain the port number from the host and enter exactly as given.");
24774 ShowMessage(
"Entry should be a number between 49152 and 59999.\n\nObtain the port number from the host and enter exactly as given.");
24783 catch(
const Exception &e)
24796 MPCPLabel3->Caption =
"Player name (2 to 4 characters)";
24803 ShowMessage(
"Entry should have at least two and at most four characters with no numbers or special characters.");
24827 ShowMessage(
"Entry should have at least two and at most four characters with no numbers or special characters.");
24837 catch(
const Exception &e)
24850 buffer.Length = 8192;
24851 buffer[0] = marker;
24852 for(bufCounter = 1; bufCounter <= UserName.Length(); bufCounter++)
24854 buffer[bufCounter] = UserName[bufCounter];
24856 if(UserName.Length() < 4)
24858 buffer[bufCounter] =
';';
24865 for(TDynamicMap::iterator DMIt = DynamicMap.begin(); DMIt != DynamicMap.end(); DMIt++)
24867 buffer[bufCounter] = DMIt->first.first;
24869 buffer[bufCounter] = DMIt->first.second.first & 0x00FF;
24871 buffer[bufCounter] = (DMIt->first.second.first & 0xFF00) / 256;
24873 buffer[bufCounter] = DMIt->first.second.second & 0x00FF;
24875 buffer[bufCounter] = (DMIt->first.second.second & 0xFF00) / 256;
24877 DMIt->second.ServiceReference = DMIt->second.ServiceReference.Trim();
24878 for(
int x = 1; x <= DMIt->second.ServiceReference.Length(); x++)
24880 buffer[bufCounter] = DMIt->second.ServiceReference[x];
24883 if(DMIt->second.ServiceReference.Length() < 8)
24885 buffer[bufCounter] =
';';
24888 buffer[bufCounter] = DMIt->second.RepeatNumber & 0x00FF;
24890 buffer[bufCounter] = (DMIt->second.RepeatNumber & 0xFF00) / 256;
24892 buffer[bufCounter] = DMIt->second.TimeToExitSecs & 0x00FF;
24894 buffer[bufCounter] = (DMIt->second.TimeToExitSecs & 0xFF00) / 256;
24903 buffer.Length = bufCounter;
24917 marker = Buffer[0];
24919 for(
int x = 1; x < 5; x++)
24921 if((Buffer[x] <
' ') || (Buffer[x] >
'~'))
24927 if(Buffer[x] ==
';')
24932 UserName[1] = Buffer[1];
24933 UserName[2] = Buffer[2];
24934 if(UserName[2] ==
';')
24936 UserName.Delete(2,3);
24941 UserName[3] = Buffer[3];
24942 if(UserName[3] ==
';')
24944 UserName.Delete(3,2);
24949 UserName[4] = Buffer[4];
24950 if(UserName[4] ==
';')
24952 UserName.Delete(4,1);
24957 while(y < (Buffer.Length - 9))
24960 NumHVPair.first = Buffer[y];
24961 NumHVPair.second.first = Buffer[y+ 1] + (256 * Buffer[y + 2]);
24962 NumHVPair.second.second = Buffer[y + 3] + (256 * Buffer[y + 4]);
24971 while((Buffer[y + z] !=
';') && (z < 8))
24978 if(Buffer[y] ==
';')
24982 ServInfo.
RepeatNumber = Buffer[y] + (256 * Buffer[y + 1]);
24983 ServInfo.
TimeToExitSecs = Buffer[y + 2] + (256 * Buffer[y + 3]);
24991 DMEntry.first = NumHVPair;
24992 DMEntry.second = ServInfo;
24993 DMap.insert(DMEntry);
25004 int bufCounter = 0;
25005 buffer.Length = 8192;
25007 buffer[0] = TTTime % 256;
25009 buffer[1] = TTTime % 256;
25011 buffer[2] = TTTime % 256;
25013 buffer[3] = TTTime % 256;
25015 for(TDynamicMap::iterator DMIt = DynamicMap.begin(); DMIt != DynamicMap.end(); DMIt++)
25017 buffer[bufCounter] = DMIt->first.first;
25019 buffer[bufCounter] = DMIt->first.second.first & 0x00FF;
25021 buffer[bufCounter] = (DMIt->first.second.first & 0xFF00) / 256;
25023 buffer[bufCounter] = DMIt->first.second.second & 0x00FF;
25025 buffer[bufCounter] = (DMIt->first.second.second & 0xFF00) / 256;
25027 DMIt->second.ServiceReference = DMIt->second.ServiceReference.Trim();
25028 for(
int x = 1; x <= DMIt->second.ServiceReference.Length(); x++)
25030 buffer[bufCounter] = DMIt->second.ServiceReference[x];
25033 if(DMIt->second.ServiceReference.Length() < 8)
25035 buffer[bufCounter] =
';';
25038 buffer[bufCounter] = DMIt->second.RepeatNumber & 0x00FF;
25040 buffer[bufCounter] = (DMIt->second.RepeatNumber & 0xFF00) / 256;
25042 buffer[bufCounter] = DMIt->second.TimeToExitSecs & 0x00FF;
25044 buffer[bufCounter] = (DMIt->second.TimeToExitSecs & 0xFF00) / 256;
25047 buffer.Length = bufCounter;
25060 TTTime = Buffer[0] + (256 * Buffer[1]) + (65536 * Buffer[2]) + (16777216 * Buffer[3]);
25061 if((TTTime < 0) || (TTTime > 34560000))
25067 while(y < (Buffer.Length - 9))
25070 NumHVPair.first = Buffer[y];
25077 NumHVPair.second.first = Buffer[y+ 1] + (256 * Buffer[y + 2]);
25078 NumHVPair.second.second = Buffer[y + 3] + (256 * Buffer[y + 4]);
25087 while((Buffer[y + z] !=
';') && (z < 8))
25094 if(Buffer[y] ==
';')
25098 ServInfo.
RepeatNumber = Buffer[y] + (256 * Buffer[y + 1]);
25099 ServInfo.
TimeToExitSecs = Buffer[y + 2] + (256 * Buffer[y + 3]);
25107 DMEntry.first = NumHVPair;
25108 DMEntry.second = ServInfo;
25109 DMap.insert(DMEntry);
25123 unsigned char UserNum;
25124 while(!ExitFile.eof())
25126 ExitFile >> UserNum;
25132 ExitFile >> ShortPair.first;
25137 ExitFile >> ShortPair.second;
25142 DMapEntry.first.first = UserNum;
25143 DMapEntry.first.second = ShortPair;
25144 DMapEntry.second = ServiceInfo;
25145 DMap.insert(DMapEntry);
25159 TDynamicMap::iterator DMIt;
25166 NumHVPair.second = TTEMMIt->first;
25167 DMIt = DMap.find(NumHVPair);
25168 if(DMIt != DMap.end())
25170 DMIt->second.ServiceReference = TTEMMIt->second.ServiceReference.Trim();
25171 DMIt->second.RepeatNumber = TTEMMIt->second.RepeatNumber;
25172 DMIt->second.TimeToExitSecs = TTEMMIt->second.TimeToExitSecs;
25185 int Dot1 = 0, Dot2 = 0, Dot3 = 0;
25186 AnsiString Num1 =
"",Num2 =
"",Num3 =
"",Num4 =
"";
25187 if(Text.Length() < 7)
25191 for(
int x = 1; x <= Text.Length(); x++)
25209 if((Dot1 ==0) || (Dot2 ==0) || (Dot3 ==0))
25213 if(Text.Length() == Dot3)
25217 Num1 = Text.SubString(1, Dot1 - 1);
25218 Num2 = Text.SubString(Dot1 + 1, Dot2 - Dot1 - 1);
25219 Num3 = Text.SubString(Dot2 + 1, Dot3 - Dot2 - 1);
25220 Num4 = Text.SubString(Dot3 + 1, Text.Length() - Dot3);
25221 if((Num1 ==
"") || (Num2 ==
"") || (Num3 ==
"") || (Num4 ==
""))
25225 if((Num1.ToInt() > 255) ||(Num2.ToInt() > 255) ||(Num3.ToInt() > 255) ||(Num4.ToInt() > 255))
25229 if((Num1.ToInt() < 0) ||(Num2.ToInt() < 0) ||(Num3.ToInt() < 0) ||(Num4.ToInt() < 0))
25235 catch(
const EConvertError &e)
25245 ServiceReference =
" ";
25247 TimeToExitSecs = -1;
25272 if(IVIt->RailwayName == RailwayName)
25274 RlyUserNumber = IVIt->RlyUserNumber;
25292 if(IVIt->UserName == UserName)
25294 RlyUserNumber = IVIt->RlyUserNumber;
25312 if(IVIt->RlyUserNumber == RlyUserNumber)
25314 RailwayName = IVIt->RailwayName;
25332 if(IVIt->UserName == UserName)
25334 UserIP = IVIt->UserIP;
25335 UserPort = IVIt->UserPort;
25353 if(IVIt->RlyUserNumber == RlyUserNumber)
25355 UserIP = IVIt->UserIP;
25356 UserPort = IVIt->UserPort;
25367 if(NumHVPair.first > 100)
25371 if((NumHVPair.second.first > 2000) || (NumHVPair.second.first < -2000))
25375 if((NumHVPair.second.second > 2000) || (NumHVPair.second.second < -2000))
25390 if((RepeatNumber < 0) || (RepeatNumber > 6000))
25394 if((TimeToExitSecs < -1) || (TimeToExitSecs > 3600))
25419 if(
InfoVector.at(x).UserName == PlayerUserName)
25509 UnicodeString Data = UnicodeString(
'3') +
MPCPUserName;
25516 UnicodeString Data = UnicodeString(
'4') +
MPCPUserName;
25522 UnicodeString Data = UnicodeString(
'6') +
MPCPUserName;
25533 Buffer.Length = 8192;
25535 if(Buffer.Length != 0)
25538 if((Buffer[0] ==
'T') && (Buffer[1] ==
'h') && (Buffer[2] ==
'e'))
25540 UnicodeString HostMessage = BytesToString(Buffer);
25541 ShowMessage(HostMessage);
25559 unsigned char UserNumber;
25564 for(
int x = 0; x < (Buffer.Length - 9); x += 10)
25566 UserNumber = Buffer[x];
25567 ShortPair.first = Buffer[x + 1] + (256 * Buffer[x + 2]);
25568 ShortPair.second = Buffer[x + 3] + (256 * Buffer[x + 4]);
25569 DMEntry.first.first = UserNumber;
25570 DMEntry.first.second = ShortPair;
25571 DMEntry.second = ServiceInfo;
25573 UserNumber = Buffer[x + 5];
25574 ShortPair.first = Buffer[x + 6] + (256 * Buffer[x + 7]);
25575 ShortPair.second = Buffer[x + 8] + (256 * Buffer[x + 9]);
25576 DMEntry.first.first = UserNumber;
25577 DMEntry.first.second = ShortPair;
25578 DMEntry.second = ServiceInfo;
25585 typedef std::pair<int, int> THLocVLocPair;
25586 THLocVLocPair HVPair;
25587 std::pair<THLocVLocPair, Graphics::TBitmap*> MPOMEntry;
25589 Graphics::TBitmap *GrPtr;
25590 HVPair.first = int(DMIt->first.second.first);
25591 HVPair.second = int(DMIt->first.second.second);
25593 if((SpeedTag < 80) || (SpeedTag > 87))
25595 throw Exception(
"Error, SpeedTag not a continuation in DynMapFromHost, value is " + AnsiString(SpeedTag));
25597 else if(SpeedTag == 80)
25601 else if(SpeedTag == 81)
25605 else if(SpeedTag == 82)
25609 else if(SpeedTag == 83)
25613 else if(SpeedTag == 84)
25617 else if(SpeedTag == 85)
25621 else if(SpeedTag == 86)
25625 else if(SpeedTag == 87)
25629 MPOMEntry.first = HVPair;
25630 MPOMEntry.second = GrPtr;
25634 MPCPLabel2->Caption =
"When ready click 'Ready to begin'";
25635 MPCPLabel4->Caption =
"Joining request accepted";
25647 Buffer.Length = 8192;
25649 if(Buffer.Length != 0)
25651 if(BytesToString(Buffer) ==
"Await simulation start")
25656 MPCPLabel2->Caption =
"Awaiting simulation start";
25682 Buffer.Length = 8192;
25684 if(Buffer.Length != 0)
25686 if(BytesToString(Buffer) ==
"Cancelled")
25696 Buffer.Length = 8192;
25698 if(Buffer.Length != 0)
25700 if(BytesToString(Buffer) ==
"Start Session")
25716 TDynamicMap::iterator DMIt, DMFHIt;
25717 Buffer.Length = 8192;
25719 if(Buffer.Length != 0)
25727 for(DMIt = DMap.begin(); DMIt != DMap.end(); DMIt++)
25732 DMFHIt->second = DMIt->second;
25746 catch(
const EIdException &e)
25751 catch(
const Exception &e)